簡體   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