Print odd and even using two threads in Java

▼魔方 西西 提交于 2019-12-23 04:09:04

问题


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.


回答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.



来源:https://stackoverflow.com/questions/27370037/print-odd-and-even-using-two-threads-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!