1

I am trying to do it using two threads like below. Can someone point the obvious mistake I am doing here?

public class OddEven {

public static boolean available = false;
public static Queue<Integer> queue = new LinkedList<Integer>();

static Thread threadEven = new Thread() {
    @Override
    public void run() {
        printEven();
    }

    public synchronized void printEven() {
        while (!available) {
            try {
                wait();
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }

        System.out.println(queue.remove());

        available = false;
        notifyAll();
    }
};

static Thread threadOdd = new Thread() {
    @Override
    public void run() {
        printOdd();
    }

    public synchronized void printOdd () {
        while (available) {
            try {
                wait();
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }

        System.out.println(queue.remove());

        available = true;
        notifyAll();
    }
};

public static void main(String[] args) {
    int n = 20;
    for (int i = 1; i < n; i++) {
        queue.add(i);
    }

    threadOdd.start();
    threadEven.start();

    try {
        Thread.sleep(60000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    try {
        threadOdd.join();
        threadEven.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

But this program is only printing 1 and quitting. After printing 1 the available should be true and printEven should wake up, print and set available to false. I don't understand what is going wrong here? I saw other solutions but want to know why my solution is not working.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
yalkris
  • 2,596
  • 5
  • 31
  • 51
  • 1
    possible duplicate of [java: Printing odd even numbers using 2 threads](http://stackoverflow.com/questions/15182418/java-printing-odd-even-numbers-using-2-threads) –  Dec 09 '14 at 01:53
  • 1
    See also: [Odd even number printing using thread](http://stackoverflow.com/q/6017281/289086), [Create two threads, one display odd & other even numbers](http://stackoverflow.com/q/13786083/289086), and [Printing Even and Odd using two Threads in Java](http://stackoverflow.com/q/16689449/289086). There are many other related questions - this is a commonly asked question. –  Dec 09 '14 at 01:54
  • While this is a popular exercise (though I don't understand why), the problem with the OP's code is not the same as the problem in the posted links. so unless I missed something I don't think closing it as a duplicate of any of these links is useful. (since this is a pretty common error there is probably another link out there that this could be a dupe of.) – Nathan Hughes Dec 09 '14 at 02:21

1 Answers1

1

Putting synchronized on an instance method means that the thread calling that method has to acquire the lock on that instance; public void synchronized printOdd() is syntax sugar for

public void printOdd() {
    synchronized(this) {
        ...
    }
}

where this is different for each instance, since ThreadOdd and threadEven are two different objects and each one uses its own lock. The methods notifyAll and wait are called on the object that is being used as the lock. When one thread waits it never gets notified because the notification only applies to other threads waiting on the same lock as the notifying thread.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Ahh... that's why I need to create a single object and pass it to both threads to be operated on. – yalkris Dec 09 '14 at 03:10