【问题标题】:How wait() and notifyAll() prevents deadlock in given code snippet?wait() 和 notifyAll() 如何防止给定代码段中的死锁?
【发布时间】:2019-02-08 07:53:36
【问题描述】:

这里是sn-p的代码:

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 个线程打印数字。一个打印奇数,另一个打印偶数。

据我了解,waitTurn 和 toggleTurn 共享实例的同一个 LOCK。因此,如果一个持有 LOCK,则另一种方法无法运行。所以如果 EvenThread 先调用 waitTurn 方法并等待轮换,它持有 LOCK,那么 OddThread 就无法进入 toggleTurn 方法并设置轮换。根据我的理解,这应该会导致僵局。但这并没有发生。

谁能解释一下为什么没有发生死锁?

【问题讨论】:

  • OddThread could NOT enter the toggleTurn 不,wait() 释放锁并允许其他线程进入。在wait() 返回之前重新获取锁。

标签: java concurrency wait deadlock notify


【解决方案1】:

"所以如果 EvenThread 先运行 waitTurn 方法并等待轮换,它持有 LOCK,OddThread 无法进入 toggleTurn 方法"

它只持有 LOCK 一小段时间,直到方法 wait() 被调用。方法wait() 释放LOCK,允许另一个线程进入临界区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    相关资源
    最近更新 更多