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(); } } }
(ArrayBlockingQueue
类提供了这项功能,因此没有理由去实现这个示例类。)
三个条件多路通信 老大通知老二,老二通知老三,老三通知老大
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(); } } } }
Lock&Condition实现线程同步通信
时间: 2024-10-22 23:43:54