厕所与内急者的对话
   —— 谈对线程Wait、Notify、NotifyAll的理解

我们假定厕所可以说话,那么一切就好办了。下面是它与他们的对话内容:

厕所:进来吧,里面没人。【方法为可用状态,还没有任何执行该方法】

男A:哦,可憋死我了。(反正没人,开门上锁就直接脱了...)【线程A开始进入某个方法并执行其内的代码块】

厕所:不好意思外面有人等着,可急着呢,你必须先出来,没完事不要紧,到旁边那小棚子里等着啊,待会儿

 我会叫你。

 【线程无奈之下调用了wait()方法,忍者小痛乖乖地出来...】

男B:哎哟,你怎么才出来啊,我都快憋爆了!【线程A退出后,线程B开始进入并执行方法内的代码块】

男B立即抢了进去,(一分钟后...)

厕所:喂,你们谁现在最急啊?过来一个,这边儿快好了。(对男B:外面的人也快憋坏了,你快点儿!)

【线程B在当前方法内遇到了notify()语句】

男B:(不好意思了)得,腿有点麻了,马上出来,别急。【线程B释放了锁】

男B出来,另一个人进去了...

(n秒过去后...)

厕所:(大家都快不行了?)现在,为了公平,你们全过来吧,谁先抢到谁先进!

【当前方法内执行了notifyAll()方法】

...结束。

为了更好地理解notify和notifyAll,套用一下马士兵的词,用我的话说就是:

notify()和notifyAll()都是厕所的使用规定,是固定的公共秩序,而不是个人主动遵守的规则。

方法内的代码对于每个执行它的线程来说都是固定不变的,不论哪个线程去执行该方法,如果在方法内

遇到了notify()语句,则该线程被强制去唤醒另一个正在等待的线程,notifyAll也一样,区别只是notifyAll

可以让等待中的线程觉得这个做法更公平。总之,notify和notifyAll不是线程的高风亮节,而是一种客观存在

(每个线程都无法摆脱)的规则。现实生活中的规律何尝不是这样呢?有了规则,大家都去遵守,才能保证社会

的正常运转。

换过来思考,如果你逻辑上认为notify和nofifyAll应该是线程自身的行为,那么我们就不应该期待每一个

执行该方法的线程都会有一致的行为,而事实上它们都得按照方法内给定的代码顺序执行,遇到notify时主动

唤醒另一个线程,遇到wait时主动停止...不是吗?

这下不奇怪为什么厕所可以说话了吧?你可以认为它不能说话,但它必须以一种方式向公众告示它的使用规定。

以上的比喻只是为了加深对线程的理解,请不要纠缠于我为什么作了这样不可接受的比喻。

因为,一旦你感觉更加不能理解,你可能陷入另一种困惑:为什么每个男的进去蹲一会

儿就主动让出来啊...内急是人之常情,但厕所这么殷勤地赶人出来可不...说多了。

    事先声明:吃饭的时候请不要看,如果看到此赶快就此打住还来得及~~。