Hello Guys !!! Hope You all are doing well.
Today I am going to discuss one of the most import concept of java Thread.
wait(), notify() and notifyAll() methods are quite obvious because they are the one of the three methods of total 9 methods from java.lang.Object. I am sharing here some practical tips and points about wait(), notify() and notifyAll() in Java and its uses in java program.
1. wait, notify and notifyAll are related to threads they are not defined in java.lang.Thread class, instead they are defined in the Object class. why? as per my understanding there are three reason :-
(A) Wait and notify is not just normal methods or synchronization utility,They are communication mechanism between two threads in Java. So An Object class is correct place to make them available for every object.
(B) Locks are made available as per Object basis, that's why wait and notify is declared in Object class rather then Thread class.
(C) As per Java design, the thread can not be specified, it is always the current thread running the code. However, we can specify the monitor (object). So it is a good design, if we could make any other thread to wait on a desired monitor.
2. We must call the wait(), notify() and notifyAll() methods from a synchronized context in Java i.e. inside synchronized method or a synchronized block.
why is this restriction??? Explanation:-
(A) The thread must hold the lock on the object it is going to call the wait() or notify() method and that is acquired when it enter into a synchronized context.
If you call it without holding a lock then they will throw IllegalMonitorStateException in Java.
(B) To avoid any potential race condition between wait() and notify() method.
3. The best approach to call wait() method from inside a loop, don't call with an if block because a thread can occasionally or irregularly awake from the wait state without being notified by another party. So in that case, this could result in a bug.
example :-
synchronized (sharedObject) {
while (condition) {
sharedObject.wait();
}
// do something
}
4. When a thread calls the wait() method in Java, it goes to the wait state by releasing the lock, which is later acquired by the other thread who can notify this thread. Here is a nice diagram of how state transition of a thread happens in Java:
5. A thread waiting due to wait() method call, then it can wake up either by calling notify() or notifyAll() method on the same object or due to interruption.
6. Difference between notify() and notifyAll() is that in case of notify() only one of the waiting thread gets a notification but in case of notifyAll() all thread get notification.
So far, we learned few basic things for wait, notify and notifyAll (which you probably already knew). Let’s write a small java program.
In this program, we will solve producer consumer problem using wait() and notify() methods.
To keep program simple, we will involve only one producer and one consumer thread.
Other features of the program are :
- Producer thread produce a new resource in every 1 second and put it in ‘taskQueue’.
- Consumer thread takes 1 seconds to process consumed resource from ‘taskQueue’.
- Max capacity of taskQueue is 7 i.e. maximum 7 resources can exist inside ‘taskQueue’ at any given time.
- Both threads run infinitely.
You can download source code from my github account
ProducerThread.java file add task in TaskQueue . Below is the full code :-
package
com.sks.softsolution.example;
import
java.util.List;
public
class
ProducerThread implements
Runnable {
private
final
List<Integer> taskQueue;
private
final
int
MAX_CAPACITY;
public
ProducerThread(List<Integer> sharedQueue,
int
size)
{
this.taskQueue
= sharedQueue;
this.MAX_CAPACITY
= size;
}
@Override
public
void
run() {
int
counter
= 0;
while
(true)
{
try
{
ProduceTask(counter++);
}
catch
(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
private
void
ProduceTask(int
i)
throws
InterruptedException
{
synchronized
(taskQueue)
{
while
(taskQueue.size()
== MAX_CAPACITY)
{
System.out.println("Queue
is full "
+ Thread.currentThread().getName()
+ "
is waiting , size: "
+ taskQueue.size());
taskQueue.wait();//calling
wait on taskQueue lock
}
Thread.sleep(1000);
taskQueue.add(i);
System.out.println("Produced:
" +
i);
taskQueue.notifyAll();
}
}
}
package
com.sks.softsolution.example;
import
java.util.List;
public
class
ConsumerThread implements
Runnable
{
private
final
List<Integer> taskQueue;
public
ConsumerThread(List<Integer> sharedQueue)
{
this.taskQueue
= sharedQueue;
}
@Override
public
void
run()
{
while
(true)
{
try
{
consumeTask();
} catch
(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
private
void
consumeTask() throws
InterruptedException
{
synchronized
(taskQueue)
{
while
(taskQueue.isEmpty())
{
System.out.println("Queue
is empty "
+ Thread.currentThread().getName()
+ "
is waiting , size: "
+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
int
i
= (Integer) taskQueue.remove(0);
System.out.println("Consumed:
" +
i);
taskQueue.notifyAll();
}
}
}
package
com.sks.softsolution.example;
import
java.util.ArrayList;
import
java.util.List;
public
class
ProducerConsumerExampleWithWaitAndNotify {
public
static
void
main(String[] args)
{
List<Integer> taskQueue
= new
ArrayList<Integer>();
int
MAX_CAPACITY
= 7;
Thread tProducer
= new
Thread(new
ProducerThread(taskQueue,
MAX_CAPACITY),
"Producer");
Thread tConsumer
= new
Thread(new
ConsumerThread(taskQueue),
"Consumer");
tProducer.start();
tConsumer.start();
}
}
Output of this program
Queue is empty Consumer is waiting , size: 0
Produced: 0
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Produced: 6
Queue is full Producer is waiting , size: 7
Consumed: 0
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Consumed: 6
Queue is empty Consumer is waiting , size: 0
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Produced: 11
Produced: 12
Produced: 13
Queue is full Producer is waiting , size: 7
Consumed: 7
Consumed: 8
Please provide your valuable feedback in comment section. it will help me to do my best.
Happy Coding!!!.....
Happy Coding!!!.....
hello,
ReplyDeletei just want to say that you have clearly mention the process very clearly and i also found it is very much easy to understand. keep sharing.
iphone app development company in chennai