zoukankan      html  css  js  c++  java
  • Lock中使用Condition实现等待通知

    • Condition类有很好的灵活性,可以实现多路通知功能,一个Lock对象中可以创建多个Condition对象实例,线程对象可以注册在指定的Condition中,进而有选择的进行线程通知,在调度线程上更加灵活
    • wait与notify/notifyAll进行等待通知时,被通知的线程是随机的,但是Condition与Lock结合的通知是有选择性的通知
    • synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有线程对象都注册在一个Condition对象身上,线程开始notifyAll时,需要通知所有的WAITING线程,没有选择性,会出现很大的效率问题
     1 public class MyService {
     2     private Lock lock = new ReentrantLock();
     3     public Condition condition = lock.newCondition();
     4     public void await(){
     5         try {
     6             lock.lock();
     7             System.out.println("await时间为"+System.currentTimeMillis());
     8             condition.await();
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         } finally {
    12             lock.unlock();
    13         }
    14     }
    15 
    16     public void signal(){
    17         try {
    18             lock.lock();
    19             System.out.println("signal时间为"+System.currentTimeMillis());
    20             condition.signal();
    21         } finally {
    22             lock.unlock();
    23         }
    24     }
    25 }
     1 public class MyThread extends Thread {
     2     private MyService service;
     3 
     4     public MyThread(MyService service) {
     5         this.service = service;
     6     }
     7 
     8     @Override
     9     public void run() {
    10         service.await();
    11     }
    12 }
     1 public class Run {
     2     public static void main(String[] args) {
     3         try {
     4             MyService service = new MyService();
     5             MyThread mt = new MyThread(service);
     6             mt.start();
     7             Thread.sleep(3000);
     8             service.signal();
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         }
    12     }
    13 }

    -------------------------------------------------------打印输出-------------------------------------------------------

    await时间为1537949157830
    signal时间为1537949160830

    Condition类中的await方法相当于Object类中的wait方法

    Condition类中的signal/signalAll方法相当于Object类中的notify/notifyAll方法

    案例2

     1 public class MyService {
     2     private Lock lock = new ReentrantLock();
     3     public Condition condition = lock.newCondition();
     4 
     5     public void awaitA(){
     6         try {
     7             lock.lock();
     8             System.out.println("begin awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
     9             condition.await();
    10             System.out.println("end awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
    11         } catch (InterruptedException e) {
    12             e.printStackTrace();
    13         } finally {
    14             lock.unlock();
    15 
    16         }
    17     }
    18 
    19     public void awaitB(){
    20         try {
    21             lock.lock();
    22             System.out.println("begin awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
    23             condition.await();
    24             System.out.println("end awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
    25         } catch (InterruptedException e) {
    26             e.printStackTrace();
    27         } finally {
    28             lock.unlock();
    29         }
    30     }
    31 
    32     public void signalAll(){
    33         try {
    34             lock.lock();
    35             System.out.println("signalAll时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
    36             condition.signalAll();
    37         } finally {
    38             lock.unlock();
    39         }
    40     }
    41 }

    线程

     1 public class ThreadA extends Thread {
     2     private MyService service;
     3 
     4     public ThreadA(MyService service) {
     5         this.service = service;
     6     }
     7 
     8     @Override
     9     public void run() {
    10         service.awaitA();
    11     }
    12 }
    13 -------------------------------------------------
    14 public class ThreadB extends Thread {
    15     private MyService service;
    16 
    17     public ThreadB(MyService service) {
    18         this.service = service;
    19     }
    20 
    21     @Override
    22     public void run() {
    23         service.awaitB();
    24     }
    25 }
     1 public class Run {
     2     public static void main(String[] args) throws InterruptedException {
     3         MyService service = new MyService();
     4         ThreadA a = new ThreadA(service);
     5         a.setName("A");
     6         ThreadB b = new ThreadB(service);
     7         b.setName("B");
     8         a.start();
     9         b.start();
    10         Thread.sleep(3000);
    11         service.signalAll();
    12     }
    13 }

    -------------------------------------------------------打印输出-------------------------------------------------------

    begin awaitA时间为1537951494924 ThreadName=A
    begin awaitB时间为1537951494925 ThreadName=B
    signalAll时间为1537951497924 ThreadName=main
    end awaitA时间为1537951497924 ThreadName=A
    end awaitB时间为1537951497925 ThreadName=B

    线程A和B都被唤醒了


    使用多个Condition实现通知部分线程

    想要单独唤醒部分线程,就需要使用多个Condition对象,先对线程进行分组,Condition对象可以唤醒部分指定线程,有助于提高程序运行效率

     1 public class MyService {
     2     private Lock lock = new ReentrantLock();
     3     public Condition conditionA = lock.newCondition();
     4     public Condition conditionB = lock.newCondition();
     5 
     6     public void awaitA(){
     7         try {
     8             lock.lock();
     9             System.out.println("begin awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    10             conditionA.await();
    11             System.out.println("--end awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    12         } catch (InterruptedException e) {
    13             e.printStackTrace();
    14         } finally {
    15             lock.unlock();
    16         }
    17     }
    18 
    19     public void awaitB(){
    20         try {
    21             lock.lock();
    22             System.out.println("begin awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    23             conditionB.await();
    24             System.out.println("--end awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    25         } catch (InterruptedException e) {
    26             e.printStackTrace();
    27         } finally {
    28             lock.unlock();
    29         }
    30     }
    31 
    32     public void signAll_A(){
    33         try {
    34             lock.lock();
    35             System.out.println("signAll_A时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    36             conditionA.signalAll();
    37         } finally {
    38             lock.unlock();
    39         }
    40     }
    41 
    42     public void signAll_B(){
    43         try {
    44             lock.lock();
    45             System.out.println("signAll_B时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
    46             conditionB.signalAll();
    47         } finally {
    48             lock.unlock();
    49         }
    50     }
    51 }

    线程

     1 public class ThreadA extends Thread {
     2     private MyService service;
     3 
     4     public ThreadA(MyService service) {
     5         this.service = service;
     6     }
     7 
     8     @Override
     9     public void run() {
    10         service.awaitA();
    11     }
    12 }
    13 -----------------------------------------------
    14 public class ThreadB extends Thread {
    15     private MyService service;
    16 
    17     public ThreadB(MyService service) {
    18         this.service = service;
    19     }
    20 
    21     @Override
    22     public void run() {
    23         service.awaitB();
    24     }
    25 }
     1 public class Run {
     2     public static void main(String[] args) throws InterruptedException {
     3         MyService service = new MyService();
     4         ThreadA a = new ThreadA(service);
     5         a.setName("A");
     6         ThreadB b = new ThreadB(service);
     7         b.setName("B");
     8         a.start();
     9         b.start();
    10         Thread.sleep(3000);
    11         service.signAll_A();
    12     }
    13 }

    -------------------------------------------------------打印输出-------------------------------------------------------

    begin awaitA时间为1537952328573 ThreadName=A
    begin awaitB时间为1537952328573 ThreadName=B
    signAll_A时间为1537952331572 ThreadName=main
    --end awaitA时间为1537952331572 ThreadName=A

    线程A被唤醒了,但是线程B仍然在等待

  • 相关阅读:
    New version of VS2005 extensions for SharePoint 3.0
    QuickPart : 用户控件包装器 for SharePoint Server 2007
    随想
    发布 SharePoint Server 2007 Starter Page
    如何在SharePoint Server中整合其他应用系统?
    Office SharePoint Server 2007 中文180天评估版到货!
    RMS 1.0 SP2
    SharePoint Server 2007 Web内容管理中的几个关键概念
    如何为已存在的SharePoint站点启用SSL
    Some update information about Office 2007
  • 原文地址:https://www.cnblogs.com/qf123/p/9708244.html
Copyright © 2011-2022 走看看