关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式,
Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Condition对象。
优势:在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,
线程对象可以注册在指定的Condition中,从而可以有选择性地对指定线程进行通知,
在调度线程上更加灵活。
实例如下:
需要下面四个类:
封装的业务方法类:MyService.java
线程A类和线程B类:ThreadA.java和ThreadB.java
运行类:Run.java
1、MyService.java
package Condition; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); public Condition conditionA = lock.newCondition();//创建conditionA对象 public Condition conditionB = lock.newCondition();//创建conditionB对象 public void awaitA(){ try{ lock.lock();//事前加lock,保证线程同步,相当于Synchronized作用 System.out.println("begin awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); conditionA.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionA对象 System.out.println(" end awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock();//最后不忘unlock() } } public void awaitB(){ try{ lock.lock(); System.out.println("begin awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); conditionB.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionB对象 System.out.println(" end awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } } public void signalAll_A(){ try{ lock.lock(); System.out.println(" signalAll_A:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); conditionA.signalAll();//选择性地通知唤醒所有绑定conditionA的对象 }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } } public void signalAll_B(){ try{ lock.lock(); System.out.println(" signalAll_B:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName()); conditionB.signalAll();//选择性地通知唤醒所有绑定conditionA的对象 }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } } }
2、ThreadA.java
package Condition; public class ThreadA extends Thread{ private MyService service; public ThreadA(MyService service){ super(); this.service = service; } @Override public void run(){ service.awaitA();//调用MyService里的awaitA()方法 } }
3、ThreadB.java
package Condition; public class ThreadB extends Thread{ private MyService service; public ThreadB(MyService service){ super(); this.service = service; } @Override public void run(){ service.awaitB();//调用MyService里的awaitB()方法 } }
4、Run.java
package Condition; public class Run { public static void main(String[] args) { MyService service = new MyService(); ThreadA a = new ThreadA(service); a.setName("线程A"); a.start(); ThreadB b = new ThreadB(service); b.setName("线程B"); b.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } service.signalAll_A();//通知唤醒绑定ConditionA的线程,使其代码继续执行 } }