wait()和notifyAll的()如何防止死锁在给定的代码片段?

问题描述 投票:0回答:1

以下是代码片段:

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方法和设置的转弯。这应该导致死锁按我的理解。但它并没有发生。

可有人请解释为什么僵局没有发生?

java concurrency wait deadlock notify
1个回答
0
投票

“所以,如果EvenThread首先运行waitTurn方法并等候转弯的变化,其持有的锁,OddThread不能进入toggleTurn法”

它拥有锁的时间只有一小段时间,直到方法wait()被调用。方法wait()解除锁定,并允许另一个线程进入临界区。

© www.soinside.com 2019 - 2024. All rights reserved.