Skip to content

Commit fc0a762

Browse files
committed
Create difference-between-wait-and-sleep.md
1 parent 7d8ef94 commit fc0a762

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## wait()和sleep()的区别
2+
3+
### 问题:
4+
在线程里`wait()``sleep()`的区别?
5+
我的理解是一条`wait()`线程语句后,仍然在运行这个模块,并且占用CPU,但是一条`sleep()`语句并不会占用CPU,对吗?
6+
为什么需要`sleep()``wait()`两条语句:他们在底层是怎么执行的?
7+
8+
### 回答:
9+
[`wait`](http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#wait%28%29)可以被另一个进程唤醒通过调用[`notify`](http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#notify%28%29)`sleep`不行。并且`wait``notify`必须在监控对象同步块内发生而`sleep`不行。
10+
```
11+
Object mon = ...;
12+
synchronized (mon) {
13+
mon.wait();
14+
}
15+
```
16+
在此刻正在执行的线程`wait`后释放了监视器。另外一个线程可能在做
17+
```
18+
synchronized (mon) { mon.notify(); }
19+
```
20+
(同一个`mon`对象)第一个线程(假设它是唯一在监视器上等待的线程)将会唤醒。
21+
如果有很多的线程在等待你可以调用[`notifyall`](http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#notifyAll%28%29)来唤醒。但是只有其中之一能抢夺到该对象的监视器并继续执行(`wait`是在`synchronized `块内)。其他的线程会被锁住直到他们获得监视器的锁。
22+
另外就是你可以`wait`对象本身(例如:你可以`wait`一个对象的监视器)但是你只能`sleep`线程。
23+
另外还有你可能会得到伪唤醒(例如:等待的线程没有任何操作就唤醒了)
24+
如果你按照下面的做法,你就能一直处于等待的状态尽管出现一些原因使他唤醒了。
25+
```
26+
synchronized {
27+
while (!condition) { mon.wait(); }
28+
}
29+
```
30+
(wait前会释放监视器,被唤醒后又要重新获取,这瞬间可能有其他线程刚好先获取到了监视器,从而导致状态发生了变化, 这时候用while循环来再判断一下条件(比如队列是否为空)来避免不必要或有问题的操作。)
31+
32+
**stackoverflow链接:**
33+
http://stackoverflow.com/questions/1036754/difference-between-wait-and-sleep
34+
35+
### 相关问题及链接:
36+
37+
1. [Java: notify() vs. notifyAll() all over again](http://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again)
38+
2. [线程通信](http://ifeve.com/thread-signaling/)

0 commit comments

Comments
 (0)