以下是代码片段:
public class PrintEvenOdd
public static class SynchronizedThreadMonitor {
public final static boolean ODD_TURN = true;
public final static boolean EVEN_TURN = false;
private boolean turn = ODD_TURN;
public synchronized void waitTurn(boolean oldTurn) {
while (turn != oldTurn) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException in wait(): " + e);
}
}
}
public synchronized void toggleTurn(){
turn ^= true;
notify();
}
}
public static class OddThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public OddThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
@Override
public void run() {
for (int i=1; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.ODD_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static class EvenThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public EvenThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
@Override
public void run() {
for (int i=2; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.EVEN_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static void main(String[] args) throws InterruptedException {
SynchronizedThreadMonitor monitor = new SynchronizedThreadMonitor();
Thread t1 = new OddThread(monitor);
Thread t2 = new EvenThread(monitor);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
使用2个线程打印数量。 One打印奇数和另一打印偶数。
在我的理解,waitTurn和toggleTurn两者共用实例的相同的锁。所以,如果一个持有该锁,其他方法无法运行。所以,如果EvenThread首先调用waitTurn方法并等候转弯的变化,其持有的锁,那么OddThread不能进入toggleTurn方法和设置的转弯。这应该导致死锁按我的理解。但它并没有发生。
可有人请解释为什么僵局没有发生?
“所以,如果EvenThread首先运行waitTurn方法并等候转弯的变化,其持有的锁,OddThread不能进入toggleTurn法”
它拥有锁的时间只有一小段时间,直到方法wait()
被调用。方法wait()
解除锁定,并允许另一个线程进入临界区。