2

I'm trying to create two threads OddThread and EvenThread which prints odd number and even number respectively. I've tried to sync those two threads to print natural numbers.

It is working fine but i don't know why it is getting into deadlock after sometime.

My code looks like this:

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();
                }
            }
        }
    }
}

Please help to to identify the cause of deadlock.

4

3 回答 3

4

You have a race condition.

If the scheduler schedules EvenThread first, it synchronizes on lock and immediately calls notify, releasing the monitor. The OddThread then acquires the lock monitor and calls wait() which releases the monitor but does not notify the EvenThread. Both threads are now waiting for a notify that will never come.

This can happen at any point during execution and is up to the Thread scheduler.

于 2013-10-26T21:54:52.880 回答
1

Here is the scenario for a dead lock:

OddThread:  waits 
EvenThread: notifies 
OddThread:  prints, notifies (EvenThread is not waiting yet! - here is the problem) 
OddThread:  waits 
EvenThread: waits 
于 2013-10-26T21:56:54.383 回答
0

Here is my modified code with semaphore which is working fine:

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();
                }
            //}
        }
    }
}

Thanks Sotirios Delimanolis and other members for helping me to find out the root cause..

于 2013-10-27T08:32:45.700 回答