我正在阅读我的SCJP书籍,目前在关于线程的章节上。我想知道为什么要使用notify。
这里是一个使用notify的示例程序:
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) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
}
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
如果我去掉 notify 调用,它仍然以相同的方式执行。即,一旦释放锁定,b.wait() 最终会停止阻塞,我们将得到一个在100000000至200000000之间的半随机数,具体取决于调度程序。
此代码:
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) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
}
}
}
无论是否存在通知,始终打印100000000。
而这段代码:
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) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
}
无论是否存在通知,始终打印出200000000。
据我所知,通知的唯一作用可能是比需要更早地唤醒线程,如果是这样,为什么要使用通知呢?为什么不等待锁释放并让JVM重新启动另一个线程呢?
Thread
对象本身。 - Jon SkeetThread
代码的某个部分在线程退出时调用了notify()
。这只是另一个不要在任意对象上加锁或等待的原因 - 只在完全控制的对象上进行操作。 - Jon Skeetwait()
*吗? - Jon Skeet