20140217 问题解决: 参考
第21章 - 并发 - 单一生产者与消费者,多个生产者与多个消费者(P709)
http://jackyin5918.iteye.com/blog/2018319
主要原因是因为使用单一锁,单一条件,使用Lock 创建两个Condition 根据不同条件调用不同condition.的signalAll()方法.
下面这个代码参考:http://www.cnblogs.com/Gordon-YangYiBao/archive/2012/09/16/2687520.html
原文说用notifyAll替代notify可解决死锁,其实不行,还是死锁,解决方法还未实现
package com.app.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* 辅助类OutTurn的一个方法输出基数,一个方法输出偶数,两个方法均有通过同步交替输出.
* 同步条件isOdd==true是输出基数,isOdd==false输出偶数
* 主类LockDemo,中实现两个runnable,OddPrinter和EvenPrinter分别输出基数和偶数
*
*/
public class LockDemo
{
private static final OutTurn ot = new OutTurn();
public static void main(String[] args)
{
// System.out.println("lock");
ExecutorService service = Executors.newCachedThreadPool();
for (int j = 0; j < 10000; j++) //这里要循环次数大一些的,否则不容易出现死锁
{
service.submit(new OddPrinter());
service.submit(new EvenPrinter());
}
service.shutdown();
}
/**
* printEven (((((((((((( 5202
printOdd ---- 5203
printEven (((((((((((( 5204
printOdd ---- 5205
printEven (((((((((((( 5206
* 运行到上面时卡住了,表示死锁了.
* 分析: 上面是输出5026后死锁的,此时isOdd=true,然后调用notify方法,此方法
* 唤醒一个线程(其他线程都处于等待状态),假如唤醒的线程还是EvenPrinter,则此线程会立即
* 执行
* while (isOdd)
{
this.wait();
}
此时,这个唯一的唤醒的线程也处于等待状态,然后 所有线程都处于等待状态了,然后导致死锁.
将所有的notify方法换成notifyAll方法 还是不行
*
*/
static class OddPrinter implements Runnable
{
@Override
public void run()
{
ot.printOdd();
}
}
static class EvenPrinter implements Runnable
{
@Override
public void run()
{
ot.printEven();
}
}
}
class OutTurn
{
private boolean isOdd = true;
private int count = 1;
public synchronized void printOdd()
{
try
{
while (!isOdd)
{
this.wait();
}
System.out.println("printOdd ---- " + count);
isOdd = false;
this.notifyAll();
}
catch (Exception e)
{
e.printStackTrace();
}
count++;
}
public synchronized void printEven()
{
try
{
while (isOdd)
{
this.wait();
}
System.out.println("printEven (((((((((((( " + count);
isOdd = true;
this.notifyAll();
}
catch (Exception e)
{
e.printStackTrace();
}
count++;
}
}