【问题标题】:why does deadlock not happen为什么不会发生死锁
【发布时间】:2019-12-16 19:52:51
【问题描述】:

死锁描述了另外两个线程因为永远相互等待而被阻塞的情况。当死锁发生时,程序永远挂起,你唯一能做的就是杀死程序。

为什么在下面给出的示例生产者消费者问题中不会发生死锁:

我想知道为什么当同步对象等待其他线程释放锁时,在同步块中调用等待方法不会导致死锁?

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class WaitAndNotify {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        var th1 = new Thread(new Producer(list));
        var th2 = new Thread(new Consumer(list));
        th1.start();
        th2.start();
    }
}

class Producer implements Runnable {

    private List<Integer> list;
    private final Integer MAX_SIZE_LIST = 5;

    public Producer(List<Integer> list) {
        this.list = list;
    }

    @Override
    public void run() {
        Random rand = new Random();
        for (;;) {
            synchronized (this.list) {
                if (list.size() == MAX_SIZE_LIST) { // check list is full or not
                    try {
                        System.out.println("list full wait producer");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                var randNumber = rand.nextInt();
                System.out.println("produce number => " + randNumber);
                list.add(randNumber);
                list.notify();
            }
        }
    }

}

class Consumer implements Runnable {

    private List<Integer> list;

    public Consumer(List<Integer> list) {
        this.list = list;
    }

    @Override
    public void run() {
        for (;;) {
            synchronized (this.list) {
                if (list.size() == 0) {
                    try {
                        System.out.println("list empty consumer wait");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("consume number <= " + list.remove(0));
                list.notify();
            }
        }
    }
}

【问题讨论】:

  • 不确定,但Consumer 可能先运行。

标签: java multithreading wait notify


【解决方案1】:

正如我们在这里已经讨论过的,由于使用了synchronized block, list.wait() and list.notify() 方法,死锁并没有发生。

这是一个很好的死锁示例:https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

【讨论】:

    【解决方案2】:

    您可能认为,Consumer 将阻止 list.wait(),而 Producer 将阻止 synchronized (this.list)

    它有效,因为list.wait()synchronized 块内释放了list 的所有权。 wait返回后,线程再次获取所有权。

    Object.wait()

    【讨论】:

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