本文共 2967 字,大约阅读时间需要 9 分钟。
多线程程序的成功运行离不开良好的通信机制。典型的生产者-消费者模式展示了线程间如何通过共享资源进行数据交换。生产者生成数据,消费者消耗数据,整个系统需确保数据的生产和消费同步进行。
在实际应用中,生产者和消费者的数据交换可以通过消息队列来实现:
isEmpty()
)?如果无数据,生成新数据并将其放入队列。take()
)?处理后,通知生产者继续产生新的数据。基于生产者-消费者的逻辑,可以得到线程模板:
此模式的实现需注意:
if
可能引发虚假唤醒。改进代码后,我们回顾线程条件判断的最优做法:
while
循环而非 if
。代码示例对比:不正确版本:
class NUM { private int number = 0; public synchronized void increment() { if (number != 0) { wait(); } number++; ... } // 其他方法类似}
改进版本:
class NUM { private int number = 0; public synchronized void increment() { while (number != 0) { wait(); } number++; ... } // 其他方法类似}
此处的关键点是将 if
判断改为 while
循环,避免物理条件判断时的错误操作。
使用 Lock
和 Condition
对象:
class NUM { private int number = 0; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void increment() { lock.lock(); try { while (number != 0) { condition.await(); } number++; System.out.println(...); condition.signalAll(); } catch (Exception e) { ... } finally { lock.unlock(); } }}
此模式的优点:
题目要求:
实现方法:
Lock
与 Condition
对象。示例代码:
class ShareResource { private int state = 0; private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); private Condition conditionC = lock.newCondition(); private Condition conditionD = lock.newCondition(); public void printA() { print(0, conditionA, conditionB); } public void printB() { print(1, conditionB, conditionC); } public void printC() { print(2, conditionC, conditionD); } public void printD() { print(3, conditionD, conditionA); } private void print(int currentState, Condition currentCondition, Condition nextCondition) { for (int i = 0; i < 10; ) { lock.lock(); try { while (state % 4 != currentState) { currentCondition.await(); } for (int j = 0; j < (state % 4 + 1); j++) { System.out.println(Thread.currentThread().getName() + " print " + (j + 1)); } state++; i++; nextCondition.signal(); } catch (InterruptedException e) { ... } finally { lock.unlock(); } } }}
上述实现:
Lock
提供更高级别的线程安全控制。转载地址:http://yklez.baihongyu.com/