首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

论wait跟notify的正确使用方法-二进制信号量的实现

2013-07-16 
论wait和notify的正确使用方法-二进制信号量的实现???????? wait和notify可以说是很神奇了,它们主要用于线

论wait和notify的正确使用方法-二进制信号量的实现

???????? wait和notify可以说是很神奇了,它们主要用于线程之间的协作,但他们却是Object类的方法。首先看看这几个方法的说明。

??????? wait:Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.

?????? notify:???? Wakes up a single thread that is waiting on this object's monitor.

?????? notifyAll:?? Wakes up all threads that are waiting on this object's monitor.

????? 从里面可以看到一个很重要的概念,就是monitor,java中每一个对象都有一个monitor,而且每个monitor都有一个等待队列,队列中放的是对该对象执行了wait的线程,对该对象执行notify(notifyall)方法,可以唤醒等待队列中的随机一个线程(全部线程)。

????? wait会让当前线程暂时放弃该对象的monitor,并且排队等候(排队是没有顺序的),notify则是拿到monitor用完的线程告诉任意一个等着的线程,“我用完了,你拿回去用吧!”值得注意的是notifyAll方法,它通知了所有等待的线程,但是还是只有一个线程能拿到monitor,剩下的线程还得继续乖乖地等着。


????? 由于wait和notify方法都会让当前线程放弃已经获得的monitor,所以每个线程只有获得了该对象的monitor,才能对其进行wait或者notify操作,在java中获得某对象的monitor的方式,就是synchronized(Object){ /*********/ }同步块,另外synchronized方法相当于synchronized(this){ /*********/ }。


????? 所以典型的使用方法是:

synchronized(object){    object.wait();}

?
还有

synchronized(object){     object.notify();}

?


另外wait方法可能会抛出InterruptedException,需要进行处理。


这篇文章的标题是wait/notify的正确使用方法,那么它的正确使用方法是什么呢?那就是不使用它!开个玩笑,我的意思是我们可以把wait和notify包装成我们喜闻乐见的东西,这样代码的可读性更好,程序也会更健壮,举个例子,我们可以用它来实现信号量Semaphore。下面是一个二进制信号量的实现。

package com.cici.lock;/** * @author 尹定宇 * @Email 768166775@qq.com * @version 2013-7-14 下午6:21:50 * @info 二进制信号量 */public class BinarySemaphore {private boolean isAvailable = false;public BinarySemaphore(){}public BinarySemaphore(boolean Available){isAvailable = Available;}public synchronized void semTake() throws InterruptedException{while(!isAvailable){wait();}this.isAvailable = false;}public synchronized void semGive(){notify();isAvailable = true;}public boolean equals(Object object){return this==object;}}

?

与直接使用wait/notify相比,信号量有诸多好处:

1.与操作系统PV操作相似,更容易理解

2.代码中不再需要出现synchronized同步块,更加美观易读

3.完美解决”假唤醒“的问题,将wait放在while循环中,若唤醒条件不具备,继续wait

4.设想一种特定的情景,我们需要一个线程先wait,然后另一个线程notify它,但是不幸地是另一个线程先notify了,所以第一个线程就永远wait了;使用信号量notify会记录在标志中,如果标志可用,就不用wait,该问题完美解决。


?

热点排行