Object类中的wait()方法和notify()方法

【Object类中的wait()方法和notify()方法】oop

wait():
	public final void wait(long timeout) throws InterruptedException
	参数:等待的时间,可选,不填则默认为0。
	说明:
		1>使线程主动释放对象锁,并进入等待状态,直到它被其余线程经过notify()或notifyAll唤醒或者超过指定的等待时间。
		2>在调用wait方法前,线程必须得到该对象的对象锁,即:只能在同步方法或同步代码块中调用wait方法,若是当前线程不是锁的持有者,将抛出一个IllegalMonitorStateException异常(是RuntimeException的子类,故不须要捕获)。
		3>wait方法执行完成后,该线程当即释放持有的对象锁(注:不是等到退出synchronized代码块后才释放)。
		4>this method should always be used in a loop:
		
			synchronized (obj) {
				// 不知足条件时等待。	
				while (condition does not hold) {	
					obj.wait();						// 注:通常会有其它的线程当条件知足后调用notify方法
				}		
				// 知足条件时执行execute方法。
				execute();					 		// 注:使用while循环保证了这行代码始终是在知足条件下被执行的!	
			}
			
			举例:
				阶段1)A线程执行该代码块时,发现不知足条件condition,则A线程进入等待状态,并释放对象锁,
				阶段2)B线程执行某些代码后,知足了条件condition,而后调用notify()方法并释放了对象锁,
				阶段3)若是此时C线程得到了该对象锁,并执行了某些代码致使又不知足条件condition了,当C线程释放该对象锁后,
				阶段4)A线程才得到了该对象锁,并执行wait()方法后面的代码。若是不使用while循环,而是使用if语句来判断(以下),则会致使execute()方法在不知足条件的状况下被执行了!
					synchronized (obj) {
						if (condition does not hold) {	
							obj.wait();
						}
						execute();
					}
			解析:
				执行execute方法的状况:
					1)执行代码块时,条件已知足,则不会调用wait方法,直接执行execute方法。
					2)执行代码块时,条件不知足,则调用wait方法,等到被唤醒后(注:被唤醒后条件可能发生变化),再去执行execute方法。
				使用while循环:保证了在调用wait方法前(阶段1)和在被唤醒后(阶段4)都去检查条件是否知足,若是知足则执行excute方法,若是不知足则继续等待。
				使用if语句:只保证了在调用wait方法前(阶段1)去检查条件是否知足,并无在线程被唤醒后去检查是否知足条件。若是发生了阶段3的状况,则execute方法将在不知足条件的状况下执行了。


notify():
	public final void notify()
	说明:
		1>随机选择一个在该对象上调用wait方法的线程,赋予其对象锁,解除其阻塞状态。
		2>在执行notify()方法后,当前线程不会立刻释放该对象锁,要等到执行notify()方法的线程退出synchronized方法或synchronized代码块后,当前线程才会释放锁,此时wait状态的线程才能够获取该对象锁,并继续执行synchronized代码块中wait()方法后面的代码。
	
	
notifyAll():
	public final void notifyAll()
	说明:唤醒在该对象上调用wait方法等待的全部线程。
	

说明:wait()、notify()、notifyAll()这三个方法:
	1)在调用方法前,线程必须得到该对象的对象锁,若是当前线程不是锁的持有者,方法将抛出一个IllegalMonitorStateException异常(是RuntimeException的子类,故不须要捕获)。
	2)只能在非静态同步方法或非静态同步代码块内调用,并且必须由锁对象来调用方法:
		1>这3个方法都是非静态方法,且这3个方法必须由锁对象调用,因此咱们不能在静态同步方法和静态代码块中调用(静态同步方法的锁是类的Class锁)。
		2>synchronized修饰的非静态方法:由于this就是锁对象,因此能够在同步方法中调用这三个方法(能够将this省略)。
		3>synchronized修饰的非静态同步代码块:必须使用锁对象来调用这三个方法。
	3)因为wait,notify和notifyAll都是锁级别的操做,而锁属于对象,故把他们定义在Object类中,而不是定义在Thread类中。
相关文章
相关标签/搜索