Home arrow Java & J2EE arrow Page 3 - More About Multithreading in Java

Inter-Thread Synchronization and Communication - Java

You are reading the second part of the multithreading in Java series. The first part covered the basics of threads, explained the theory that lies behind them, and then gave examples of the two possible ways of creating new threads. This article resumes the journey by getting even deeper into concepts like the ThreadGroup class, synchronization, and inter-thread communication.

TABLE OF CONTENTS:
  1. More About Multithreading in Java
  2. Stopping and Synchronization
  3. Inter-Thread Synchronization and Communication
  4. Taking a Break
By: Barzan "Tony" Antal
Rating: starstarstarstarstar / 16
March 04, 2009

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement
 

Inter-thread communication is all about making synchronized threads communicate with each other. Sometimes one might want to pause (or delay) the execution of a thread until some condition is met. And this condition only occurs if another thread does such and such. To implement these, inter-thread communication is necessary.

Java offers three possible solutions. The following three methods are inherited from the Object class: public final void wait(), public final void notify(), public final void notifyAll(). The first method forces a thread to wait until some other thread calls either notify() or notifyAll() methods. The second notify() method wakes up the thread that invoked the wait() method on the same object. And the third method, notifyAll(), wakes up all of the threads that called the wait() method on the same object. 

As mentioned earlier, wait() is defined in the Object class, and it can only be called from a synchronized thread. It may throw an InterruptedException. In short, it releases the lock it is holding on an objectís monitor, thereby allowing other threads to run. The notify() method wakes up any of the threads that are waiting to release the objectís monitor lock. This choice is arbitrary and at the discretion of the JVM. 

The awakened threads will resume execution right from where they were paused. The same applies to notifyAll(). Now letís explain the producer-consumer model. Imagine the shelf of a bookstore, for example. The producer places books on the shelf, while the consumer grabs them. There are two conditions necessary. First, there should be books on the shelf for the consumer to grab. And second, if there are too many books on the shelf, then there isn't any space left for more books. 

The producer and consumer model consists basically of two synchronized threads that should communicate with each other. Itís not that hard at all, but if it is neglected, the results can be disastrous. So this problem is going to implement two of the major concepts we have learned in this article: thread synchronization and inter-thread communication. All right, so letís begin writing the code!

 

public class Books{

private int count;

private boolean isReady = false;

 

public synchronized int grab(){

while (isReady == false){

try{

wait();

}

catch (InterruptedException e){}

}

isReady = false;

notifyAll();

return count;

}

 

public synchronized void place(int newCount){

while (isReady == true){

try{

wait();

}

catch (InterruptedException e){}

count = newCount;

isReady = true;

notifyAll();

}

}

}

 

And now the implementation of the Producer class:

 

public class Producer extends Thread{

private Books myShelf;

private int number;

 

public Producer(Books b, int number){

myShelf = b;

this.number = number;

}

 

public void run(){

for (int i = 0; i < 5; ++i){

myShelf.place(i);

System.out.println("Prod No#: " + this.number + " places " +i);

try{

sleep(10);

}

catch (InterruptedException e){}

}

}

}

 

Finally, here comes the Consumer class as well. Check it out below.

 

public class Consumer extends Thread{

private Books myShelf;

private int number;

 

public Consumer(Books b, int number){

myShelf = b;

this.number = number;

}

 

public void run(){

int val = 0;

for (int i = 0; i < 5; ++i){

val = myShelf.grab();

System.out.println("Cons No#: " + this.number + " grabs " +val);

}

}

}

 

All that is left is creating a class with public static void main, so that we can launch this application. The last snippet is below.

 

public class MyClass{

public static void main (String args[]){

Books b = new Books();

Producer p = new Producer (b, 1);

Consumer c = new Consumer (b, 1);

 

p.start();

c.start();

}

}

 

And finally, hereís the attached output. Check it out. And weíre done for now!

 

Prod No#: 1 places 0

Cons No#: 1 grabs 0

Prod No#: 1 places 1

Cons No#: 1 grabs 1

Prod No#: 1 places 2

Cons No#: 1 grabs 2

Prod No#: 1 places 3

Cons No#: 1 grabs 3

Prod No#: 1 places 4

Cons No#: 1 grabs 4



 
 
>>> More Java & J2EE Articles          >>> More By Barzan "Tony" Antal
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

JAVA & J2EE ARTICLES

- More Java Bugs Lead to More Attacks
- Oracle's Java One Brings News, Surprises
- Oracle Patches Java Runtime Environment
- Apple Syncs Java Update with Oracle
- Spring 3.1 Java Development Framework Compat...
- Jelastic Java PaaS Availability and Pricing ...
- NetBeans 7.1 Released, Supports JavaFX 2
- SolarWinds Releases Newest Version of Java M...
- Free Monitoring Tool for Java Apps on Heroku
- Heroku Adds JCloud Platform Support, Java 7 ...
- Java SE 8 Speculation in Full Swing
- Java SE 7 Now Available
- New JVM Language and Java Reporting Tool
- Java 7 Release Update and New Eclipse Toolkit
- The Best Java Netbeans IDE Plugins

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: