Search code examples
javamultithreadingwaitnotify

Does wait() wait for the referenced object or the reference itself if called on a reference?


In this case, will thread 1 actually be notified (while waiting for the reference instead of the object itself)?

static Object lock=new Object();
//Thread 1:
Object reference=lock;
reference.wait();

//Thread 2:
lock.notify();

Solution

  • Waiting for the reference or the object pointed to by that reference is the same thing since a lock is obtained on an object. No matter how many references are there, if they point to the same object in memory wait(), notify(), notifyall() will work seamlessly. Check out the code below.

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.ArrayBlockingQueue;
    
    public class ProducerConsumer {
    
    private Queue<Integer>      queue   = new ArrayBlockingQueue<>(10);
    private LinkedList<Integer> list    = new LinkedList<>();
    int                         limit   = 10;
    
    public static void main(String[] args) {
    
        final ProducerConsumer pc = new ProducerConsumer();
        final ProducerConsumer pcRef = pc;
    
        Thread producer = new Thread(new Runnable() {
            int i = 1;
    
            @Override
            public void run() {
                while (true) {
                    synchronized (pcRef) {
                        while (pc.limit == pc.list.size()) {
                            try {
                                pcRef.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        pc.list.add(i);
                        System.out.println("Producer @work : " + pc.list.size());
                        pcRef.notify();
                    }
    
                }
            }
        });
    
        Thread consumer = new Thread(new Runnable() {
    
            @Override
            public void run() {
                while (true) {
                    synchronized (pc) {
                        while (0 == pc.list.size()) {
                            try {
                                pc.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        int val = pc.list.removeFirst();
                        System.out.println("Consumer @work : " + pc.list.size() + " : " + val);
                        pc.notify();
                    }
    
                }
            }
        });
    
        producer.start();
        consumer.start();
    
        try {
            producer.join();
            consumer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
    }
    
    }
    

    Comment the below line and you will see that the consumer thread is waiting to be notified.

    pc.list.add(i);
    System.out.println("Producer @work : " + pc.list.size());
    //pcRef.notify();