简体   繁体   中英

why does deadlock not happen

Deadlock describes a situation where two more threads are blocked because of waiting for each other forever. When deadlock occurs, the program hangs forever and the only thing you can do is to kill the program.

why deadlock does not happen in example producer consumer problem given below:

I wonder why call wait method in synchronized block does not causing deadlock when synchronized object is waiting for release of lock from other thread ?

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

You probably think, that Consumer will block at list.wait() and Producer will block at synchronized (this.list) .

It works, because list.wait() releases the ownership of list inside a synchronized block. After wait returns, the thread acquires the ownership again.

See Object.wait()

As we have already discussed here Deadlock did not happen because of the use of synchronized block, list.wait() and list.notify() methods.

Here is a nice example of deadlock : https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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