繁体   English   中英

为什么不会发生死锁

[英]why does deadlock not happen

死锁描述了由于永远等待而又阻塞了两个线程的情况。 当发生死锁时,程序将永远挂起,您唯一能做的就是杀死该程序。

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

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

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将在list.wait()list.wait()而Producer将在list.wait() synchronized (this.list)处阻塞。

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

参见Object.wait()

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM