首页 > 解决方案 > 为什么不会发生死锁

问题描述

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

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

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

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();
            }
        }
    }
}

标签: javamultithreadingwaitnotify

解决方案


您可能认为,thatConsumer将阻止 atlist.wait()并且 Producer 将阻止 at synchronized (this.list)

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

参见Object.wait()


推荐阅读