当前位置: 首页 > 知识库问答 >
问题:

为什么死锁不会发生

何超英
2023-03-14

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

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

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

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

共有2个答案

习和通
2023-03-14

正如我们已经在这里讨论过的,死锁没有发生,因为使用了同步块,列表.wait()和list.notify()方法。

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

越朗
2023-03-14

你可能会认为,使用者将在 list.wait() 处阻止,而生产者将在同步(此列表)处阻止。

这是可行的,因为< code>list.wait()在< code>synchronized块中释放了< code>list的所有权。在< code>wait返回后,线程再次获得所有权。

见Object.wait()

 类似资料:
  • 问题内容: 输出: 问题答案: 之所以陷入僵局,是因为结构是通过值而不是通过引用传递的。 将WaitGroup传递给函数时,需要传递 指针 而不是值。否则,将使用WaitGroup的副本。 这是您的工作示例:

  • 此问题的完整代码可在此处获得:https://github.com/NACHC-CAD/thread-tool 下面显示的代码似乎一直运行到完成,但从未逃脱此处显示的while循环。 如果我取消注释

  • 本文向大家介绍请谈一谈,什么情况下会发生死锁?解决死锁的策略有哪些?相关面试题,主要包含被问及请谈一谈,什么情况下会发生死锁?解决死锁的策略有哪些?时的应答技巧和注意事项,需要的朋友参考一下 考察点:死锁 (一)互斥条件:一个资源一次只能被一个进程访问。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占 有。这种独占资源如CD-ROM驱动器,打印机等等,必须在占有该资源的进

  • 本文向大家介绍什么是线程死锁?如何避免死锁?相关面试题,主要包含被问及什么是线程死锁?如何避免死锁?时的应答技巧和注意事项,需要的朋友参考一下 认识线程死锁 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态

  • 我正在调查。 我有一个问题,在C#winfo:什么是错误的,在这个异步的例子,如果访问结果之前等待上面的问题已经解决。这是一个死锁问题。 但是当我在stackoverflow中搜索一些问题时。我发现了这个:async/wait不同的线程ID 应该也是个僵局问题吧? 我重写了一个类似的代码来测试 代码运行良好,不会阻塞。代码结果显示: < code >任务。结果不会出现死锁。 我的问题是: < li

  • Hibernate是我的JPA实现。