我正在浏览线程,并且我读到notify()
方法用于向同一个对象的等待池中等待的一个且仅有一个线程发送信号。方法notifyAll()
的工作方式与notify()
相同,只是它将信号发送到等待Object
的所有线程。
现在我的查询是,如果让我说我有5个线程和一个主线程,那么最初主线程启动,然后其他五个线程启动。现在我想只向第三个线程发送通知。怎么可能使用notify()
,因为在这里我只向第三个线程发送通知?请指教。
答案 0 :(得分:3)
如果您希望通知特定线程,请将其wait()
放在其他对象上,然后在此对象上调用notify()
。
答案 1 :(得分:3)
ReentrantLock类通过允许每个对象有多个等待集,为您提供比synchronized
关键字更精细的粒度控制。
您可以使用ReentrantLock.newCondition()
从Conditions获得多个ReentrantLock。然后一个线程可以调用Condition.await()
(类似于Object.wait()
的功能)并将阻塞直到另一个线程调用Condition.signal()
(类似于Object.notify()
的功能)。
不同的是,您可以为单个Conditions
创建多个ReentrantLock
。因此,您可以为每个Condition
创建一个Thread
,并在与您想要唤醒的signal()
对应的条件下调用Thread
。
这是一个简单的示例代码,用于演示上述内容。它会创建5个Threads
,所有这些都会在同一Conditions
的不同ReentrantLock
上等待。主线程然后调用signal()
来唤醒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( );
}
}
}
这应该打印以下内容:
开始线号0
开始第1号线
开始第2号线
开始第3号线
开始第4号线
唤醒Thead 3号
第3号线醒了!