import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ConditionCommunication {    final Business business = new Business();    public static void main(String[] args) {        new ConditionCommunication().init();    }    private void init() {        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i <= 50; i++) {                    business.sub(i);                }            }        }).start();        for (int i = 0; i <= 50; i++) {            business.main(i);        }    }    class Business {        private boolean bShouldSub = true;        Lock lock = new ReentrantLock();        Condition condition = lock.newCondition();        public void sub(int i) {            lock.lock();            try {                while (!bShouldSub) {                    condition.await();                }                for (int j = 1; j <= 10; j++) {                    System.out.println("sub thread sequence of" + j                            + ",loop of " + i);                }                bShouldSub = false;                condition.signal();            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }        public synchronized void main(int i) {            lock.lock();            try {                while (bShouldSub) {                    condition.await();                }                for (int j = 1; j <= 20; j++) {                    System.out.println("main thread sequence of" + j                            + ",loop of " + i);                }                bShouldSub = true;                condition.signal();            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }}

阻塞队列实现

两个condition实现只唤醒对方

作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。 class BoundedBuffer {   final Lock lock = new ReentrantLock();   final Condition notFull  = lock.newCondition();    final Condition notEmpty = lock.newCondition();    final Object[] items = new Object[100];   int putptr, takeptr, count;   public void put(Object x) throws InterruptedException {     lock.lock();     try {       while (count == items.length)          notFull.await();       items[putptr] = x;        if (++putptr == items.length) putptr = 0;       ++count;       notEmpty.signal();     } finally {       lock.unlock();     }   }   public Object take() throws InterruptedException {     lock.lock();     try {       while (count == 0)          notEmpty.await();       Object x = items[takeptr];        if (++takeptr == items.length) takeptr = 0;       --count;       notFull.signal();       return x;     } finally {       lock.unlock();     }   }  }

( 类提供了这项功能,因此没有理由去实现这个示例类。)

三个条件多路通信  老大通知老二,老二通知老三,老三通知老大

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ThreeThreadConditionCommunication {    final Business business = new Business();    public static void main(String[] args) {        new ThreeThreadConditionCommunication().init();    }    private void init() {        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i <= 50; i++) {                    business.sub2(i);                }            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i <= 50; i++) {                    business.sub3(i);                }            }        }).start();                for (int i = 0; i <= 50; i++) {            business.main(i);        }    }    class Business {        private int flag = 1;        Lock lock = new ReentrantLock();        Condition condition1 = lock.newCondition();        Condition condition2= lock.newCondition();        Condition condition3= lock.newCondition();        public void sub2(int i) {            lock.lock();            try {                while (flag!=2) {                    condition2.await();                }                for (int j = 1; j <= 10; j++) {                    System.out.println("sub2 thread sequence of" + j                            + ",loop of " + i);                }                flag = 3;                condition3.signal();            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }        public void sub3(int i) {            lock.lock();            try {                while (flag!=3) {                    condition3.await();                }                for (int j = 1; j <= 10; j++) {                    System.out.println("sub3 thread sequence of" + j                            + ",loop of " + i);                }                flag =1;                condition1.signal();            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }                public synchronized void main(int i) {            lock.lock();            try {                while (flag!=1) {                    condition1.await();                }                for (int j = 1; j <= 20; j++) {                    System.out.println("main thread sequence of" + j                            + ",loop of " + i);                }                flag = 2;                condition2.signal();            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }}