首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

一个简单产生死锁的线程协作

2014-01-19 
一个容易产生死锁的线程协作import java.util.ArrayListimport java.util.Listimport java.util.concurr

一个容易产生死锁的线程协作
import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Plate {private List<Object> eggs = new ArrayList<Object>();public synchronized Object getEgg() {while(eggs.size() == 0) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}Object egg = eggs.get(0);eggs.clear(); //清空notifyAll(); // 唤醒阻塞队列的某线程进入就绪队列System.out.println("拿到鸡蛋");return egg;}public synchronized void addEgg(Object egg) {while (eggs.size() > 0) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}eggs.add(egg);notifyAll();System.out.println("放入鸡蛋");}public static void main(String[] args) {Plate plate = new Plate();ExecutorService exec = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {exec.execute(new GetEggThread(plate));exec.execute(new AddEggThread(plate));}exec.shutdown();}}

?认真比较两段代码的差异,不难发现:notify() 改成 notifyAll()。为什么使用notify会导致死锁呢?可以解释为:

notify() 只会唤醒一个等待的线程,被唤醒的线程不一定能获当前释放的锁。

使用notify()而不是notifyAll()是一种优化。使用notify时,在众多等待的任务中只有一个会被唤醒。因此如果你希望使用notify(),就必须保证被唤醒的是恰当的任务。

在实际的程序中,很难做到使用notify()只唤醒恰当的任务(只有两个线程的情况除外)。因此,更多的时候我们使用notifyAll()。notifyAll() 将唤醒“所有正在等待的任务”这个说法并不正确。只唤醒等待当前锁的线程。

热点排行