condition 的作用:条件锁
需求:
按需执行三个线程。
用wait,notify的方式:
/** * 有序线程 wait,notify版 */ public class OrderThreadW_NVersion { private int flag=0; public synchronized void A(){ while (flag != 0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("A"); flag=1; notifyAll(); } public synchronized void B(){ while (flag != 1){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("B"); flag=2; notifyAll(); } public synchronized void C(){ while (flag != 2){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("C"); flag=0; notifyAll(); } public static void main(String[] args) { OrderThreadW_NVersion ot = new OrderThreadW_NVersion(); new Thread(()->{ while (true){ ot.A(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); new Thread(()->{ while (true){ ot.B(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); new Thread(()->{ while (true){ ot.C(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
缺点:
notifyAll,会唤醒所有等待的线程,不能指定特定线程的唤醒。此时就引入了condition
用condition的方式来实现:
/** * 有序线程,conditin版 */ public class OrderThreadCondition { private int flag = 0; Lock lock = new ReentrantLock(); Condition a = lock.newCondition(); Condition b = lock.newCondition(); Condition c = lock.newCondition(); public void A() { lock.lock(); while (flag != 0) { try { a.await();//跟object的wait一样 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("A"); flag = 1; b.signal();//唤醒指定线程 lock.unlock(); } public void B() { lock.lock(); while (flag != 1) { try { b.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("B"); flag = 2; c.signal(); lock.unlock(); } public void C() { lock.lock(); while (flag != 2) { try { c.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("C"); flag = 0; a.signal(); lock.unlock(); } public static void option(OrderThreadCondition ot,String methodName){ while (true){ try { Method method = ot.getClass().getMethod(methodName, null); method.invoke(ot,null); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } } public static void main(String[] args) { OrderThreadCondition ot = new OrderThreadCondition(); new Thread(() -> option(ot,"A")).start(); new Thread(() -> option(ot,"B")).start(); new Thread(() -> option(ot,"C")).start(); } }