java - 为什么不会发生死锁
问题描述
死锁描述了另外两个线程因为永远互相等待而被阻塞的情况。当死锁发生时,程序永远挂起,你唯一能做的就是杀死程序。
为什么在下面给出的示例生产者消费者问题中不会发生死锁:
我想知道为什么当同步对象等待其他线程释放锁时,同步块中的调用等待方法不会导致死锁?
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();
}
}
}
}
解决方案
您可能认为,thatConsumer
将阻止 atlist.wait()
并且 Producer 将阻止 at synchronized (this.list)
。
它有效,因为释放了块内部list.wait()
的所有权。返回后,线程再次获得所有权。list
synchronized
wait
推荐阅读
- javascript - Redux坚持黑名单删除reducer?
- javascript - JavaScript 自动填充问题
- python-3.x - 有人可以解释一下为什么 plyer filechooser 在我的 android 设备上不起作用吗?
- python - Tensorflow-GPU 不使用带有 CUDA、CUDNN 的 GPU
- python - QPushButton 快捷方式无法正常工作
- c# - 高效的 For 循环 Unity C#
- python - 通过每个线程的每一行文本文件进行多处理迭代以进行登录
- awk - 将 bash 中的特殊字符(α、β)写入输出文件 - 编码不正确
- node.js - 类图上 expressJS 中的 GET 和 POST 请求
- applescript - LibreOffice:递归转换文件夹和子文件夹中的文档