This article contains two code examples to demonstrate Java concurrency. They stand for very typical usage. By understanding them, you will have a better understanding about notify() and wait().
1. Some background knowledge
synchronized
keyword is used for exclusive accessing.- To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
- Synchronized statements must specify the object that provides the intrinsic lock. When synchronized(this) is used, you have to avoid to synchronizing invocations of other objects’ methods.
-
wait()
tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ). -
notify()
wakes up the first thread that calledwait()
on the same object.
2. notify() and wait() – example 1
public class ThreadA { public static void main(String[] args){ ThreadB b = new ThreadB(); b.start(); synchronized(b){ try{ System.out.println("Waiting for b to complete..."); b.wait(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("Total is: " + b.total); } } } class ThreadB extends Thread{ int total; @Override public void run(){ synchronized(this){ for(int i=0; i<100 ; i++){ total += i; } notify(); } } } |
In the example above, an object, b, is synchronized. b completes the calculation before Main thread outputs its total value.
Output:
Waiting for b to complete... Total is: 4950
If b is not synchonized like the code below:
public class ThreadA { public static void main(String[] args) { ThreadB b = new ThreadB(); b.start(); System.out.println("Total is: " + b.total); } } class ThreadB extends Thread { int total; @Override public void run() { for (int i = 0; i < 100; i++) { total += i; } } } |
The result would be 0, 10, etc. Because sum is not finished before it is used.
3. notify() and wait() – example 2
The second example is more complex, see the comments.
import java.util.Vector; class Producer extends Thread { static final int MAXQUEUE = 5; private Vector messages = new Vector(); @Override public void run() { try { while (true) { putMessage(); //sleep(5000); } } catch (InterruptedException e) { } } private synchronized void putMessage() throws InterruptedException { while (messages.size() == MAXQUEUE) { wait(); } messages.addElement(new java.util.Date().toString()); System.out.println("put message"); notify(); //Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object. } // Called by Consumer public synchronized String getMessage() throws InterruptedException { notify(); while (messages.size() == 0) { wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep. } String message = (String) messages.firstElement(); messages.removeElement(message); return message; } } class Consumer extends Thread { Producer producer; Consumer(Producer p) { producer = p; } @Override public void run() { try { while (true) { String message = producer.getMessage(); System.out.println("Got message: " + message); //sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String args[]) { Producer producer = new Producer(); producer.start(); new Consumer(producer).start(); } } |
A possible output sequence:
Got message: Fri Dec 02 21:37:21 EST 2011 put message put message put message put message put message Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011 put message put message put message put message put message Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011 Got message: Fri Dec 02 21:37:21 EST 2011
in example 1 : if the object is another type of object(another class or user defined object) it works well.But in this example thread is used so we can’t say when the thread executes . wait function may be executed before or after the thread calls its depends on system speed. So here we cant use threads if u use threads u can use these methods thread.isAlive(),thread.join() and thread.isDaemon() for checking the thread executed or running.
Example#1 is really bad example. If `notify()` invokes before `b.wait()`, then you get a deadlock.
Because Main thread itself gets ‘Blocked on Monitor’ and So, there is no thread to start the b thread.
Hello friends!
I am an official representative of private company which deals with all kinds of written work (essay, coursework, dissertation, presentation, report, etc) in short time.
We are ready to offer a free accomplishment of written work hoping for further cooperation and honest feedback about our service.
Send your work topics to our email: [email protected]. This offer has limited quantities!!!
Agree. Adding a “Thread.sleep(4000);” right after “b.start()” would demonstrate it.
Can somebody please explain why in example 1, if I move b.start(); to below the synchronized(b) block, the output is always “Waiting for b to complete…”?
synchronized(b){
try{
System.out.println(“Waiting for b to complete…”);
b.wait();
} catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(“Total is: ” + b.total);
}
b.start();
Output: “Waiting for b to complete…”
SInce b.wait() inside the block would release the lock and wait, why didn’t the program continue with b.start() and complete, so that the block can continue?
Please delete this shit so others won’t waste their time
My take on the first example. Added a sleep to simulate a notify too before the wait and a condition check to avoid thread lock:
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
try {
Thread.sleep(1000); // simulate a notify() before the wait()
}
catch (InterruptedException e) {
}
synchronized(b){
try{
System.out.println(“Waiting for b to complete…”);
while (b.isAlive()) { //condition guarantees no thread lock occurs
b.wait();
}
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(“Total is: ” + b.total);
}
}
}
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}
Why we should always call wait method in loop
know how to you satisfy yahoo offer us an case in point of a accurate instance 1 by means of Runnable?
It looks like in example#2 code in getMessage() is broken… notify() method call is too early which’ll wake up thread(s) already in m’s waitSet ( which exactly is thread called putMessage() ). notify() should be places at the end of getMessage() method.
Can you please provide us an example of a correct Example 1 using Runnable?
Yes, you can try this example and once a while it will lock up.
> Below is example of wait notify 1st customer is trying to withdrawal
> money 2000 but account is having only 1000 Rs so wait for deposit,
> once deposit is completed then customer will able to withdrawal
> amount ..till deposit customer is waiting.
package com.thread.example;
class Cust{
private int totalAmount=1000;
public synchronized void withdrwl(int amount){
System.out.println(“Total amount “+totalAmount +” withdrwling amount “+amount);
if(this.totalAmount<amount){
System.out.println("not enogh amount..waiting for deposite..");
try{wait();}catch(Exception e){}
}
this.totalAmount-=amount;
System.out.println("Withrawl successful..Remaining balance is "+totalAmount);
}
public synchronized void deposite(int amount){
System.out.println("Depositing amount "+amount);
this.totalAmount+=amount;
System.out.println("deposit completed…and Now totalAmount is "+this.totalAmount);
notify();
}
}
class Depo implements Runnable{
Cust c; int depo;
Depo(Cust c, int depo){
this.c=c;
this.depo=depo;
}
@Override
public void run() {
c.deposite(depo);
}
}
class Withdrawl implements Runnable{
Cust c; int with;
Withdrawl(Cust c, int with){
this.c=c;
this.with=with;
}
@Override
public void run() {
c.withdrwl(with);
}
}
public class MainClass {
public static void main(String[] args) {
Cust c = new Cust();
Thread w = new Thread(new Withdrawl(c, 2000));
Thread d= new Thread(new Depo(c, 1000));
w.start();
d.start();
}
}
I agree. You should use b.join(); which will force the main thread to wait until the calculation is complete
this is perfect for example #1 to understand more on wait()
Quick hack: In that case, we can avoid wait “forever” with “b.wait(someTime)”.
call to wait() method should be with in a loop that checks the condition on which the thread is waiting. That’s a recommendation as per java docs to avoid a scenario known as spurious wakeup.
Read more about it here – http://netjs.blogspot.com/2015/07/inter-thread-communiction-wait-notify-java-multi-thread.html
This example won’t work if notify() is called before wait() is called . If it is the case, then main thread will wait/block forever . To make sure wait() is called 1st then before b.start() , we issue wait() command . Am I right ?
“b.wait()” will cause the current thread (i.e. the main thread) to wait until another thread has called one of the notify-methods of “b”. Since no other thread has access to “b”, other than “b” itself, the main thread will wait “forever”.
Looks fine form me ,
main thread will start, then thread b will start and get the lock then completes its calculation. After that second block of synchronization will start and after printing “waiting for the thread b to complete….” it will call .wait() method to release the lock. Then again normal main thread will execute and prints the total.
But I wanted a more complex example so that we can understand more . This is very simple example and not elaborating much
nope – UR right on a closer look.
“It only works if the main thread gets the hold of the monitor for ‘b’ before ‘b’ itself does.”
I don’t see how this is true.
b.start(); is starting b before main thread gets its lock
b finishes its execution, gets into TERMINATED state and releases its lock
main thread acquires b’s lock and gets into the synch’d block
reads the value total and prints it out.
package com.scjp.thread;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class SychModification {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
AddItem addItem = new AddItem(linkedList, “Adding Thread”);
AddItem addItem1 = new AddItem(linkedList, “Adding Thread1”);
// AddItem addItem2 = new AddItem(linkedList, “Adding Thread2”);
RemoveItem removeItem = new RemoveItem(linkedList,
“Removing Item Thread”);
removeItem.start();
addItem.start();
addItem1.start();
// addItem2.start();
}
}
class AddItem extends Thread {
private List list;
private static int count = 0;
public AddItem(List list, String name) {
super(name);
this.list = list;
}
@Override
public void run() {
while (true) {
try {
synchronized (list) {
System.out.println(“Adding value from ” + getName());
list.add(“Add ITEM” + count++);
list.notifyAll();
}
Thread.sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
class RemoveItem extends Thread {
private List list;
public RemoveItem(List list, String name) {
super(name);
this.list = list;
}
@Override
public void run() {
while (true) {
try {
synchronized (list) {
list.wait();
if(!list.isEmpty())
System.out.println(((Queue) list).remove());
System.out.println(list.size());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
what is the name of second program..before psvm their should be a class name.
what is the name of second program..before psvm their should be a class name…
Can anyone explain why this program is getting stopped..
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName(“ThreadB”);
System.out.println(Thread.currentThread().getName()+” 1 “+b.getState());
b.start();
try {
b.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+” 2 “+b.getState());
synchronized(b){
try{
System.out.println(“Waiting for b to complete…”);
System.out.println(Thread.currentThread().getName()+” 3 “+b.getState());
b.wait();
System.out.println(Thread.currentThread().getName()+” 4 “+b.getState());
}catch(InterruptedException e){
e.printStackTrace();
}
}
// System.out.println(“C Total is: ” + c.total);
System.out.println(“B Total is: ” + b.total);
System.out.println(Thread.currentThread().getName()+” 5 “+b.getState());
}
}
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
this.notify();
System.out.println(Thread.currentThread().getName()+" run 3 "+getState());
}
}
}
Output:
main 1 NEW
Thread-0 run 3 RUNNABLE
main 2 TERMINATED
Waiting for b to complete…
main 3 TERMINATED
—————————-
Program is still running but it doesn't get end.
Is it a deadlock?
Easier way to see that is to devide the numbers to pairs in this way:
(1+99)+(2+98)….+(49+51)+50=49*(100)+50. Just an anakdote i hope you like.
Example 1 is an absolutely hideous example of programming by coincidence: http://pragprog.com/the-pragmatic-programmer/extracts/coincidence
It only works if the main thread gets the hold of the monitor for ‘b’ before ‘b’ itself does.
The only way to assure this, is to make ThreadB implement Runnable (or use it as the one it already is) and then run it from a thread started from inside the ‘synchronized(b) { … }’ statement.
Thanks. I knew that the answer is a piece of cake
int i = 0; i < 100… this means the range of numbers [0,99]. If you add those numbers together you get 4950…. using the formula N(N+1)/2 where N is your largest number in this case 99
99(99+1)/2 = 4950
Sorry for damn question but why the result of the first example is 4950? How did it happen?
When you have to extend some other class and still use multithreading then you can use implements runnable as in java you wont be able to extend two classes at the same time.
Vishal
asdasd
Thank you for the information.
I have doubt on threads can u tell me please when I have to use extends threads and implements and what is the difference between…
Modified first program:
public class ThreadA
{
public static void main(String[] args) throws InterruptedException
{
ThreadB b = new ThreadB();
b.start();
// Thread.sleep(500);
if(!b.finished)
synchronized (b)
{
try
{
System.out.println(“Waiting for b to complete…”);
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(“Total is: ” + b.total);
}
}
class ThreadB extends Thread
{
int total;
boolean finished;
@Override
public void run()
{
synchronized (this)
{
for (int i = 0; i < 100; i++)
{
total += i;
}
finished = true;
notify();
}
}
}
Totally agree, before call to b.wait() there should be a check that will verify whether ThreadB completed its execution.
If ThreadB be will aquire the lock before threadA then notify() will be called before wait() method. Then ThreadB will release the lock and we enter in synchronized block of ThreadA – wait() method will be called and program will hang cause notify() was already called before…
Great code example.I want to add that while wait method is present in the object class, sleep method is present in the Thread class. This means that we can’t invoke sleep() method on any object. Some beginners don’t understand the locking mechanism used by wait and sleep methods in java