Inter thread Communication methods:
These methods are define inside Object, as display here
final void wait ( ) throws InterruptedException
final void notify( )
final void notifyAll( )
Further forms of wait ( ) exist which permits you to specify a period of time to wait.
The given sample program incorrectly implements an easy form of the producer/customer problem. That consists of four classes: Q, the queue in which you're trying to synchronize; Producer, the threaded object which is producing queue entries; A Consumer, the threaded object which is consuming queue entries; and PC the tiny class which creates the single Q, Consumer and Procedure.
// An incorrect implemention of a consumer and producer
class Q {
int n;
synchronized int get( ) {
System.out.println("Got: " +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(thos,"Producer").start( ) ;
}
public void run( ) {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implement Runnable {
Q,q;
Consumer(Q,q) {
this.q= q;
new Thread(this,"Consumer").
start( ) ;
}
public void run( ) {
while(true) {
q.get( );
}
}
}
class PC {
public static void main(String args[ ] ) {
Q,q = new Q( );
new Producer(q);
new Consumer(q);
System.out.println("Press Control-c to stop.");
}
}
Although the put( ) and get( ) functions on Q are synchronized, nothing stops the producer from overrunning the consumer, nor will anything stop the consumer from consuming the similar queue value double. Thus you get the erroneous output displays here:
Put :1
Got :1
Got :1
Got :1
Got :1
Got :1
Put :2
Put :3
Put :4
Put :5
Put :6
Put :7
Got :7
As you can see earlier, after the producer put 1, the consumer begins and got the similar 1 five times in a row. After that the procedure resumed and produced 2 through 7 without letting the consumer have a chance to consume them.
The actual way to write this program in Java is to use wait( ) and notify( ) to signal within both directions as displays here:
//A correct implemetation of a consumer and procedure
class Q {
int n;
boolean valueSet = false;
synchronized int get( ) {
if(!valueSet)
try {
wait( );
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
return n;
}
System.out.println("Got: "+n);
valueSet = false;
notify( ) ;
synchronized void put(int n){
if(!valueSet)
try {
wait( );
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n; valueSet = true;
System.out.println("Put: "+n);
notify( ) ;
}
}
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 implement Runnable { Q,q;
Consumer(Q,q) {
this.q= q;
new Thread(this,"Consumer").start( ) ;
}
public void run( ) {
while(true) {
q.get( );
}
}
}
class PCFixed {
public static void main(String args[ ] ) {
Q,q = new Q( );
new Producer(q);
new Consumer(q);
System.out.println("Press Control-c to stop.");
}
}
Within get( ), wait( ) is called. This causes its execution to suspend until the Producer notifies you in which a few data is ready. Whenever this happens, execution within get( ) resumes. After the data has been get, get( ) calls notify( ). That tells Product which it is okay to put more data in the queue. Within put( ), wait( ) suspends execution until the Consumer has erased the item form the queue. Whenever execution resumes, the further item of data is put in the queue, and notify( ) is called. This tells the Consumer in which it should now remove it.
Here is a few output from this program, that displays the clean synchronous behavior.
put : 1
Got : 1
put : 2
Got : 2
put : 3
Got : 3
put: 4
Got :4
put: 5
Got: 5