Java:MultiThread同步,导致死锁

时间:2013-10-26 21:45:01

标签: java multithreading

我正在尝试创建两个线程 OddThread EvenThread ,它们分别打印奇数和偶数。我试图同步这两个线程来打印自然数字。

它工作正常,但我不知道为什么它会在一段时间后陷入僵局。

我的代码如下所示:

public class NaturalNoPrint {
    public static void main(String[] args) {
        Object lock = new Object();
        Thread oddThread = new Thread(new OddThread(lock));
        Thread evenThread = new Thread(new EvenThread(lock));
        oddThread.start();
        evenThread.start();
    }
}

class OddThread implements Runnable{
    private int no=1;
    private Object lock;

    OddThread(Object lock){
        this.lock=lock;
    }
    public void run(){
        while(true){
            synchronized(lock){
                try {           
                    lock.wait();
                    System.out.println(no);
                    no+=2;
                    lock.notify();
                    Thread.sleep(1000);         
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class EvenThread implements Runnable{
    private int no=2;
    private Object lock;

    EvenThread(Object lock){
        this.lock=lock;
    }
    public void run(){
        while(true){
            synchronized(lock){
                try{            
                    lock.notify();
                    lock.wait();
                    System.out.println(no);
                    no+=2;
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

请帮助确定死锁的原因。

3 个答案:

答案 0 :(得分:4)

你有竞争条件。

如果调度程序首先调度EvenThread,它会在lock上同步并立即调用notify,从而释放监视器。然后,OddThread会获取lock监视器并调用wait()来释放监视器但不会notify EvenThread。两个线程现在都在等待永远不会来的notify

这可能在执行期间的任何时候发生,并且由Thread调度程序决定。

答案 1 :(得分:1)

以下是死锁的情况:

OddThread:  waits 
EvenThread: notifies 
OddThread:  prints, notifies (EvenThread is not waiting yet! - here is the problem) 
OddThread:  waits 
EvenThread: waits 

答案 2 :(得分:0)

这是我修改后的信号量代码,工作正常:

public class NaturalNoPrint {
    public static void main(String[] args) {
        Semaphore oddMutex = new Semaphore(0);
        Semaphore evenMutex = new Semaphore(0);
        Thread oddThread = new Thread(new OddThread(oddMutex,evenMutex));
        Thread evenThread = new Thread(new EvenThread(oddMutex,evenMutex));
        evenThread.start();
        oddThread.start();
    }
}

class OddThread implements Runnable{
    private int no=1;
    private Semaphore oddMutex,evenMutex;
    OddThread(Semaphore oddMutex,Semaphore evenMutex){
        this.oddMutex=oddMutex;
        this.evenMutex=evenMutex;
    }

    public void run(){
        while(true){
            //synchronized(lock){
                try {           
                    //lock.wait();
                    oddMutex.acquire();
                    System.out.println(no);
                    no+=2;
                    Thread.sleep(1000); 
                    //lock.notify();
                    evenMutex.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            //}
        }
    }
}


class EvenThread implements Runnable{
    private int no=2;
    //private Object lock;
    private Semaphore oddMutex,evenMutex;

    EvenThread(Semaphore oddMutex,Semaphore evenMutex){
        this.oddMutex=oddMutex;
        this.evenMutex=evenMutex;
    }
    public void run(){
        while(true){
            //synchronized(lock){
                try{            
                    //lock.notify();
                    //lock.wait();
                    oddMutex.release();
                    evenMutex.acquire();
                    System.out.println(no);
                    no+=2;
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            //}
        }
    }
}

感谢 Sotirios Delimanolis 和其他成员帮助我找出根本原因..