我正在练习java多线程和并发。所以我目前正在研究 wait() 和 notification() 功能。我创建了以下代码
public class WaitAndNotifyTest {
public static void main(String[] args) {
Object testString = new Object();
RunnableImplTest runnableImplTest = new RunnableImplTest(testString);
for(int i=0; i<5; i++) {
Thread thread = new Thread(runnableImplTest);
System.out.println("Created thread " + thread.getName());
thread.start();
}
synchronized (testString) {
testString.notify();
}
}
private static class RunnableImplTest implements Runnable{
private Object str;
public RunnableImplTest(Object str) {
this.str = str;
}
@Override
public void run() {
try {
synchronized (str) {
System.out.println("Sending in waiting state for thread "+Thread.currentThread().getName());
str.wait();
System.out.println("Waiting completion for thread " + Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Got the control for "+Thread.currentThread().getName());
}
}
}
我创建了这段代码来检查notify()如何从等待线程列表中选择一个线程以允许进一步执行。
现在我得到上述代码的以下输出
Created thread Thread-0
Created thread Thread-1
Created thread Thread-2
Sending in waiting state for thread Thread-0
Created thread Thread-3
Sending in waiting state for thread Thread-1
Created thread Thread-4
Sending in waiting state for thread Thread-2
Sending in waiting state for thread Thread-3
Sending in waiting state for thread Thread-4
Waiting completion for thread Thread-0
Got the control for Thread-0
根据我的代码,我期望synchronized关键字应该锁定线程X的监视器对象,并且任何其他线程不应该被允许在它们自己的
RunnableImplTest
实例中进入该块,因为我已经在多个线程之间共享了监视器对象线程。
这在 JavaDoc 中记录了 Object.wait()(注意添加了强调):
请注意,这是必需的:否则主线程如何执行此方法导致当前线程(此处称为 T)将自身置于该对象的等待集中,然后 放弃该对象上的所有同步声明。
synchronized (testString) {
testString.notify();
}
如果 testString
上的锁仍由您启动的任何线程持有。顺便说一句,
testString
是一个可怕的名字:它不是一个字符串,它与测试没有任何关系,它分散了人们对其目的的理解。