解决方案 »

  1.   

    0 in
    3 in
    2 in
    1 in
    2 out(sleep)
    3 out(decrease)
    0 out(increase)
    1 out(increase)
    2 in
    main exit
    3 exit
    1 exit
    0 exit
    2 out(decrease)
    2 exit
    这是一个测试的例子
    大家可以看到
    2 in
    之后程序就死锁了
    直到
    main exit
    才有
    2 out
      

  2.   

    按理说3 decrease在忙循环中等待很正常
    但是为甚0 1 2线程,都停止了呢?
    大家看ThreadMain构造 ,是有100组Integer的
    不可能是因为队列空而,等待
    0和1甚至根本没输出in
    说明0 1死锁在increase中
    2死锁在poll中
    是因为3一直在synchronized decrease中吗?
    synchronized不是只限制同函数不被同时执行吗
    为什么3 decrease
    导致
    0 1 2 调用的函数均失败了?
      

  3.   

    0 in
    3 in
    2 in
    2 out(sleep)
    1 in
    1 out(increase)
    1 in
    1 out(decrease)
    3 out(decrease)
    3 in
    3 out(sleep)
    0 out(increase)
    0 in
    0 out(increase)
    0 in
    1 in
    0 out(decrease)
    1 out(sleep)
    2 in
    2 out(increase)
    2 in
    2 out(decrease)
    0 in
    0 out(sleep)
    3 in
    3 out(increase)
    3 in
    2 in
    2 out(sleep)
    3 out(decrease)
    1 in
    1 out(increase)
    1 in
    3 in
    3 out(decrease)
    1 out(sleep)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    3 in
    3 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    0 out(sleep)
    2 out(decrease)
    1 in
    1 out(increase)
    1 in
    1 out(decrease)
    2 in
    2 out(sleep)
    3 in
    3 out(increase)
    3 in
    1 in
    3 out(decrease)
    1 out(sleep)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    3 in
    3 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    2 out(decrease)
    0 out(sleep)
    1 in
    1 out(increase)
    1 in
    2 in
    2 out(sleep)
    1 out(decrease)
    3 in
    3 out(increase)
    3 in
    1 in
    1 out(decrease)
    3 out(sleep)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    1 in
    1 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    0 out(sleep)
    2 out(decrease)
    3 in
    3 out(increase)
    3 in
    3 out(decrease)
    2 in
    2 out(sleep)
    1 in
    1 out(increase)
    1 in
    3 in
    3 out(sleep)
    1 out(decrease)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    0 in
    0 out(sleep)
    3 in
    3 out(increase)
    3 in
    3 out(decrease)
    1 in
    2 in
    2 out(sleep)
    1 out(increase)
    3 in
    3 out(decrease)
    1 in
    1 out(sleep)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    3 in
    3 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    0 out(sleep)
    2 out(decrease)
    1 in
    1 out(increase)
    1 in
    1 out(decrease)
    2 in
    2 out(sleep)
    3 in
    3 out(increase)
    3 in
    1 in
    1 out(decrease)
    3 out(sleep)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    1 in
    1 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    0 out(sleep)
    2 out(decrease)
    3 in
    3 out(increase)
    3 in
    3 out(decrease)
    2 in
    2 out(sleep)
    1 in
    1 out(increase)
    1 in
    3 in
    1 out(decrease)
    3 out(sleep)
    0 in
    0 out(increase)
    0 in
    1 in
    0 out(decrease)
    1 out(sleep)
    2 in
    2 out(increase)
    2 in
    0 in
    0 out(decrease)
    2 out(sleep)
    3 in
    3 out(increase)
    3 in
    3 out(decrease)
    0 in
    0 out(sleep)
    1 in
    1 out(increase)
    1 in
    1 out(decrease)
    3 in
    3 out(sleep)
    .......ConcurrentLinkedQueue本来就是线程安全的
    把add和poll的synchronized去掉后
    输出如上,可见已经正常运行了
    可是为什么死锁还是没有头绪 ,大家有什么看法?
      

  4.   

    我上面的说法有些错误,我重发一下代码
    import java.util.concurrent.ConcurrentLinkedQueue;public class Routine {
    public static final void main(String[] args) {
    ThreadMain m = new ThreadMain();
    try {
    Thread.sleep(20000);
    } catch (InterruptedException e) {
    }
    m.getData().setRun(false);
    System.out.print("main exit\n");
    }
    }class ThreadData {
    private boolean mRun;
    private ConcurrentLinkedQueue<Integer> mWait;
    private int mValue; public ThreadData() {
    mRun = true;
    mWait = new ConcurrentLinkedQueue<Integer>();
    mValue = 0;
    } public void add(Integer i) {
    mWait.add(i);
    } public Integer poll() {
    return mWait.poll();
    } public void increase(Integer i) {
    mValue += i.intValue();
    } public synchronized void decrease(Integer i) {
    while (mRun && mValue < i.intValue())
    ;
    if (mRun) {
    mValue -= i.intValue();
    }
    } public boolean getRun() {
    return mRun;
    } public void setRun(boolean r) {
    mRun = r;
    }
    }class ThreadMain implements Runnable {
    private ThreadData mData;
    private Thread[] mRuns; public ThreadMain() {
    mData = new ThreadData();
    for (int i = 0; i < 100; i++)
    mData.add(Integer.valueOf((int) (Math.random() * 200)));
    mRuns = new Thread[4];
    for (int i = 0; i < mRuns.length; i++) {
    mRuns[i] = new Thread(this);
    mRuns[i].start();
    }
    } @Override
    public void run() {
    String[] names = { "increase", "decrease", "sleep" };
    int mId ;
    for (mId = 0 ; mId < mRuns.length && Thread.currentThread() != mRuns[mId] ; mId++) ;

    while (mData.getRun()) {
    Integer i;
    System.out.printf("%d in\n", mId);
    do {
    i = mData.poll();
    } while (mData.getRun() && i == null);
    if (mData.getRun() == false)
    break;
    System.out.printf("%d out(%s)\n", mId, names[i.intValue() % 3]); switch (i.intValue() % 3) {
    case 0:
    mData.increase(i);
    break;
    case 1:
    mData.decrease(i);
    break;
    case 2:
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
    break;
    }
    } System.out.printf("%d exit\n", mId);
    } public ThreadData getData() {
    return mData;
    }
    }
    正确的 ,测试输出
    1 in
    3 in
    2 in
    0 in
    2 out(increase)
    3 out(decrease)
    1 out(decrease)
    3 in
    3 out(sleep)
    2 in
    2 out(sleep)
    0 out(increase)
    0 in
    0 out(increase)
    1 in
    0 in
    1 out(decrease)
    0 out(sleep)
    1 in
    1 out(increase)
    1 in
    1 out(sleep)
    3 in
    0 in
    0 out(decrease)
    2 in
    2 out(decrease)
    2 in
    2 out(decrease)
    2 in
    2 out(decrease)
    0 in
    0 out(increase)
    0 in
    0 out(decrease)
    1 in
    1 out(sleep)
    3 out(sleep)
    1 in
    1 out(decrease)
    3 in
    3 out(decrease)
    main exit
    0 exit
    2 exit
    1 exit
    3 exit
    我发现问题还出在increase的synchronized

    下面是increase加了synchronized的
    死锁的 ,测试输出
    0 in
    3 in
    1 in
    2 in
    1 out(increase)
    3 out(decrease)
    0 out(decrease)
    1 in
    1 out(decrease)
    2 out(increase)
    main exit
    0 exit
    1 exit
    2 exit
    3 exit
      

  5.   

    看⑨楼
    错误输出
    2 out
    之后,程序就没反应了
    直到
    main exit
    各个线程才退出
    2 out(increase)
    指的是2线程成功从队列中获取数据,接下来执行increase操作
    你再看看increase函数
    这个函数可能会让线程2执行那么久吗
    只有一个可能2被挂起了
    但是这个函数会引起线程拥挤吗
    显然不会!!!
    但是线程2还是被挂起了
    这不是死锁是什么还有我原本是学c的
    我按照这段代码 ,用c++和临界区写了个同样思路的代码
    结果完全正常 ,不管我在哪个函数加临界区
    程序都正常执行
    但换到java就这样
    是java执行太慢吗?
    是我没理解synchronized吗?
    我怎么想都不合理最后只得出一个结论
    java就是这样罢了
      

  6.   

    还有请看清楚
    最后我发的代码是没问题的
    有问题的代码是这段代码的increase函数
    加上了synchronized
    才会引起问题哎,算了,我结贴了
    如果有人明白了请@我,求教
    如果不知道发生了什么问题
    或者没时间去研究,那就ctrl+w吧