Search code examples
javamultithreadingmonitor

Monitor (semaphore) in java


I have been reading and performing practical in java from the Book "The Complete Reference " by Herbert Schildt.
In this book in Thread chapter, there is a section of Interthread Communication.
One side book says no other synchronized method of an instance is executed by any thread until a current thread terminates but have a look at the program below.
In output it executes both synchronized methods how could someone explain what is happening?

output:

put :0
put :1
put :2
put :3
put :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4

class Main{
    public static void main(String args[]){
        Q q=new Q();

        Producer p=new Producer(q);
        Consumer c=new Consumer(q); 
    }
}

class Q {
    int n;

    synchronized int get(){
        System.out.println("get :"+n);
        return n;
    }
    synchronized void put(int n){
        this.n=n;
        System.out.println("put :"+n);
    }
}



class Producer implements Runnable{
    Q q;
    Producer(Q q){
        this.q=q;
        new Thread(this,"Producer").start();

    }
    public void run(){
        int i=0;
        while(true){
            q.put(i++);
        }
    }
}

class Consumer implements Runnable{
    Q q;
    Consumer(Q q){
        this.q=q;
        new Thread(this,"Consumer").start();
    }

    public void run(){
        while(true){
            q.get();
        }
    }
}

Solution

  • Extracting from Java docs,

    it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object

    So there, termination means not the thread itself (e.g: Consumer does not wait until Producer dies or completed, vice-versa), but execution completion of any synchronizing methods/blocks.

    To answer your question, still Producer and Consumer both can run using Q, but both get and put methods will never be executed at same time, because of implicit synchronization with object instance with keyword synchronized.

    Only one method will be executed by either Producer or Consumer at any given time, i.e. when get is called by Consumer, Producer cannot call put and vice-versa.