我正在阅读我的SCJP书,我正在关于线程的章节,我想知道为什么你应该使用通知。
以下是我使用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++;
}
}
}
如果我取消通知电话,它仍然以相同的方式执行。 I.E.,一旦锁被释放,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。
据我所知,通知所做的唯一事情可能是早于需要唤醒线程,如果是这样的话,为什么要使用notify呢?为什么不等待释放锁并让JVM重新启动另一个线程?
答案 0 :(得分:3)
除非您或其他人致电notify()
,否则wait()
应该永远继续,除非是虚假的醒来。你确定什么都没有打断线程吗?
基本上你精确地使用notify()
来唤醒线程。如果您不需要让线程进入休眠状态,直到另一个线程可以通知它应该唤醒它,请不要使用它。
wait()
。我的猜测是,当线程终止时,Thread
对象会收到通知。
尝试等待共享的Object
,如下所示:
class ThreadA {
static Object monitor = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(monitor) {
try {
System.out.println("Waiting for b to complete...");
monitor.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(ThreadA.monitor) {
for (int i = 0; i < 100000000; i++) {
total++;
}
// ThreadA.monitor.notify();
}
}
}
如果取消注释该行,程序将终止 - 否则不会。
编辑:我实际上已经找到了一些关于此的文档。来自Thread.join(millis, nanos)
:
当一个线程终止时,将调用this.notifyAll方法。建议应用程序不要在Thread实例上使用wait,notify或notifyAll。