geekoff
geekoff

Reputation: 152

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

Upvotes: 0

Views: 135

Answers (2)

Madhuri Kadam
Madhuri Kadam

Reputation: 154

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

Upvotes: 0

MofX
MofX

Reputation: 1567

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

Upvotes: 3

Related Questions