用实例揭示notify()和notifyAll()的本质区别

中国人最喜欢访问的网站
只要注册ofo就送你10块钱,还等什么,快来注册吧

notify()notifyAll()都是Object对象用于通知等待该对象的线程的方法。

notifyAll使所有原来在该对象上等待的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,它们就会去竞争。
notify则只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notifynotifyAll,它们等待的是被notifynotifyAll,而不是锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Cafe {
}
class CafeFactory {
List<Cafe> finishedCafe = new ArrayList<Cafe>();
public void addCafe() {
try {
while (true) {
Thread.sleep(5000);// act busy
Cafe w = new Cafe();
// 也就是说需要5秒钟才能新产生一个Widget,这决定了一定要用notify而不是notifyAll
// 因为上面两行代码不是同步的,如果用notifyAll则所有线程都企图冲出wait状态
// 第一个线程得到了锁,并取走了Widget(这个过程的时间小于5秒,新的Widget还没有生成)
// 并且解开了锁,然后第二个线程获得锁(因为用了notifyAll其他线程不再等待notify语句
// ,而是等待finishedWidgets上的锁,一旦锁放开了,他们就会竞争运行),运行
// finishedWidgets.remove(0),但是由于finishedWidgets现在还是空的,
// 于是产生异常
// ***********这就是为什么下面的那一句不能用notifyAll而是要用notify
synchronized (finishedCafe) {
System.out.println(Thread.currentThread() + " Adding cafe:" + w);
finishedCafe.add(w);
finishedCafe.notify(); // 这里只能是notify而不能是notifyAll
}
}
} catch (InterruptedException e) {
}
}
public Cafe getCafe() {
synchronized (finishedCafe) {
if (finishedCafe.size() == 0) {
try {
finishedCafe.wait();
} catch (InterruptedException e) {
}
}
Cafe c = finishedCafe.remove(0);
System.out.println(Thread.currentThread() + "Getting cafe:" + c);
return c;
}
}
}
class AddingCafeTask implements Runnable {
private CafeFactory cafeFactory;
public AddingCafeTask(CafeFactory cafeFactory) {
this.cafeFactory = cafeFactory;
}
@Override
public void run() {
cafeFactory.addCafe();
}
}
class GetingCafeTask implements Runnable {
private CafeFactory cafeFactory;
public GetingCafeTask(CafeFactory cafeFactory) {
this.cafeFactory = cafeFactory;
}
@Override
public void run() {
cafeFactory.getCafe();
}
}
public class CafeTest extends Thread {
public static void main(String[] args) {
CafeFactory cafeFactory = new CafeFactory();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new GetingCafeTask(cafeFactory));
executorService.execute(new GetingCafeTask(cafeFactory));
executorService.execute(new GetingCafeTask(cafeFactory));
executorService.execute(new AddingCafeTask(cafeFactory));
}
}
快下载安装吧,今天头条送你钱啦!!!!
中国人都在使用的地球上最好玩的游戏
中国人都在使用的地球上最好玩的游戏
中国人都在使用的地球上最快的浏览器
中国人都在使用的地球上最厉害的安全软件
中国人都在使用的地球上最好的看图王
中国人都在使用的地球上最快速的视频软件
中国人都在使用的地球上最全的视频软件
中国人都在使用的地球上最好最全的压缩软件
中国人都在使用的地球上最好的音乐播放器
中国人都在使用的地球上最安全的杀毒软件
中国人都在使用的地球上最全的影视大全