Condition精准唤醒和通知
关键字synchornized可以使用wait()和notify()方法实现等待/通知模式,在类ReentrantLock中也可以实现相同的功能,但需要借助java.util.concurrent.locks 下的Condition对象。
使用Condition比synchornized拥有更好的灵活性,它可以在一个Lock对象中创建多个实例,线程对象可以在指定的Condition对象中选择性的进行线程通知,在下线程调度上更为灵活
在使用wait()和notify()方法进行等待通知时,被调度的线程是被JVM随机选择的,使用ReentrantLock结合Condition可以实现精准通知
Condition中的基本方法:
1.await():对应Object的wait()方法,是线程休眠
2.signal(): 对应Object的notify()方法,唤醒线程
3.signalAll():对应Object的notifyAll()方法,唤醒所有线程
下面使用condition和lock实现一个等待通知模式:
在资源类中有三个方法,创建三个线程,让这三个方法按顺序依次执行
public class ConditionTest { public static void main(String[] args) { Test1 test1 = new Test1(); new Thread(()->{ for (int i = 0; i < 10; i++) { test1.printA(); } },"A").start(); new Thread(()->{for (int i = 0; i < 10; i++) { test1.printB(); }},"B").start(); new Thread(()->{for (int i = 0; i < 10; i++) { test1.printC(); }},"C").start(); } } class Test1{ private Lock lock = new ReentrantLock(); //三个线程用三个不同的监视器 private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); private int number = 1;// number为1是A执行;2时B执行;3时C执行 public void printA(){ lock.lock(); try {//业务,判断 -》 执行 - 》 通知 while (number != 1){ //等待 condition1.await(); } System.out.println(Thread.currentThread().getName()+"=>AAA"); //唤醒,唤醒指定的线程 number = 2; condition2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printB(){ lock.lock(); try {//业务,判断 -》 执行 - 》 通知 while (number != 2){ //等待 condition2.await(); } System.out.println(Thread.currentThread().getName()+"=>BBB"); //唤醒,唤醒指定的线程 number = 3; condition3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printC(){ lock.lock(); try {//业务,判断 -》 执行 - 》 通知 while (number != 3){ //等待 condition3.await(); } System.out.println(Thread.currentThread().getName()+"=>CCC"); //唤醒,唤醒指定的线程 number = 1; condition1.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }