Reputation: 41
I was going through threads and I read that the notify()
method is used to send a signal to one and only one of the threads that are waiting in that same object's waiting pool. The method notifyAll()
works in the same way as notify()
, only it sends the signal to all of the threads waiting on the Object
.
Now my query is that if let's say I have 5 threads and one main thread, so initially the main thread starts and then five other threads start. Now I want to send notification to third thread only. How could it be possible with the use of notify()
, since here I am sending notification to third thread only? Please advise.
Upvotes: 1
Views: 163
Reputation: 5423
The ReentrantLock class gives you more fined grained control than the synchronized
keyword by allowing multiple wait sets per object.
You can get multiple Conditions from a ReentrantLock using ReentrantLock.newCondition()
. A thread may then call Condition.await()
(similar in function to Object.wait()
) and will block until another thread calls Condition.signal()
(similar in function to Object.notify()
).
The difference is you can create multiple Conditions
for a single ReentrantLock
. So you could create one Condition
for each Thread
and call signal()
on the condition corresponding to the Thread
which you wanted to wake up.
Here's a simple example code which demonstrates the above. It creates 5 Threads
which all wait on different Conditions
of the same ReentrantLock
. The main thread then calls signal()
to wake up a specific one of the Threads
.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ReentranLockTest
{
public static void main( String[] args )
{
final ReentrantLock lock = new ReentrantLock( );
int numThreads = 5;
Condition[] conditions = new Condition[numThreads];
// start five threads, storing their associated Conditions
for ( int i = 0; i < numThreads; i++ )
{
final int threadNumber = i;
System.out.printf( "Started thread number %d%n", threadNumber );
// to create a Condition we must lock the associated ReentrantLock
lock.lock( );
try
{
final Condition condition = lock.newCondition( );
conditions[i] = condition;
// start the worker Thread
( new Thread( )
{
@Override
public void run( )
{
// wait on the Condition
// to do so we must be holding the
// associated ReentrantLock
lock.lock( );
try
{
condition.await( );
}
catch ( InterruptedException e )
{
e.printStackTrace( );
}
finally
{
lock.unlock( );
}
// print something when signal()
// is called on our Condition
System.out.printf( "Thread number %d woke up!%n", threadNumber );
}
} ).start( );
}
finally
{
lock.unlock( );
}
}
// acquire the ReentrantLock and call
// Condition.signal() to wake up Thread number 3
lock.lock( );
try
{
System.out.printf( "Waking up Thead number %d%n", 3 );
conditions[3].signal( );
}
finally
{
lock.unlock( );
}
}
}
This should print the following:
Started thread number 0
Started thread number 1
Started thread number 2
Started thread number 3
Started thread number 4
Waking up Thead number 3
Thread number 3 woke up!
Upvotes: 3
Reputation: 137432
If you want a specific thread to be notified, let it wait()
on a different object, and call notify()
on this object.
Upvotes: 3