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