IUnknown
IUnknown

Reputation: 9829

Deadlock on initialization

Why does this get into a deadlock immediately on start - it prints a line and then freezes(after the edits advised)?
This is probably because the firstthread misses the notify trigger before it starts waiting.
What is the resolution?

public class threadTwo{
    AtomicInteger i=new AtomicInteger(0);
    Boolean b=new Boolean(false);

    class firstThread implements Runnable{
        AtomicInteger i;
        Boolean b;
        firstThread(AtomicInteger i,Boolean b){
            this.i=i;
            this.b=b;
        }
        public void run(){
            while(true){
                synchronized(i){
                    try{
                        while(b==false)
                            i.wait();

                        if(i.intValue()<30){
                            i.incrementAndGet();
                            System.out.println( Thread.currentThread().getId() + " - " + i.intValue());
                        }
                        b=false;
                        i.notify();

                    }catch(InterruptedException x){}
                }
            }
        }       
    }

    class secondThread implements Runnable{
        AtomicInteger i;
        Boolean b;
        secondThread(AtomicInteger i,Boolean b){
            this.i=i;
            this.b=b;
        }
        public void run(){
            while(true){
                synchronized(i){
                    try{
                        while(b==true)
                                i.wait();

                        if(i.intValue()<40){
                            i.getAndAdd(2);
                            System.out.println( Thread.currentThread().getId() + " - " + i.intValue());
                        }
                        b=true;
                        i.notify();

                    }catch(InterruptedException x){}
                }
            }
        }       
    }

    void runThread(){ 
        Thread t1 = new Thread(new firstThread(i,b));
        Thread t2 = new Thread(new secondThread(i,b));
        t1.start();
        t2.start();
        try{
            t1.join();
            t2.join();
        }catch(Exception e){}
        System.out.println("Result : " + i.intValue());
    }

    public static void main(String[] args){
        new threadTwo().runThread();

    }

}

Upvotes: 0

Views: 137

Answers (2)

Chiranjib
Chiranjib

Reputation: 1783

If I guessed the intentions of the code correctly, then there's needless synchronization and wait-notify. Try this instead:

public class MyThread
{
    AtomicInteger i = new AtomicInteger(0);
    Boolean b = new Boolean(false);

    class FirstThread implements Runnable
    {
        AtomicInteger i;
        Boolean b;

        FirstThread(AtomicInteger i, Boolean b)
        {
            this.i = i;
            this.b = b;
        }

        public void run()
        {
            while (i.intValue() < 30)
            {
                i.incrementAndGet();
                System.out.println(Thread.currentThread().getId() + " - " + i.intValue());
            }
        }
    }

    class SecondThread implements Runnable
    {
        AtomicInteger i;
        Boolean b;

        SecondThread(AtomicInteger i, Boolean b)
        {
            this.i = i;
            this.b = b;
        }

        public void run()
        {
            while (i.intValue() < 40)
            {
                i.getAndAdd(2);
                System.out.println(Thread.currentThread().getId() + " - " + i.intValue());
            }
        }
    }

    void runThread()
    {
        Thread t1 = new Thread(new FirstThread(i, b));
        Thread t2 = new Thread(new SecondThread(i, b));
        t1.start();
        try
        {
            t1.join();
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        t2.start();
        try
        {
            t2.join();
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println("Result : " + i.intValue());
    }

    public static void main(String[] args)
    {
        new MyThread().runThread();

    }
}

Upvotes: 0

guenhter
guenhter

Reputation: 12177

The Problem is b.wait() in the firstThread. This variable b is never notified from secondThread, because, the secondThread fails on the check if(b==true) and returns immediately.

But also be aware of the fact, that the sync via the Variable b is very bad, because the statements b=false; and b=true; are assigning new instances to the variables and therefore firstThread and secondThread lose their connection.

Upvotes: 2

Related Questions