【多线程整理 3】wait方法

wait()

当一个线程调用一个共享变量的 wait()方法时,该调用线程会被阻塞挂起,直到发生下面几件事情之一才返回:

(1)其他线程调用了该共享对象的notify()或者notifyAll()方法;

(2)其他线程调用了该线程的interrupt()方法,该线程抛出InterruptedException异常返回。

另外需要注意的是,如果调用wait()方法的线程没有事先获取该对象的监视器锁,则调用 wait()方法时调用线程会抛出IllegalMonitorStateException异常。

获取一个共享变量的监视器锁有以下两种常用方法:

(1)执行synchronized 同步代码块时,使用该共享变量作为参数。 

(2)调用该共享变量的方法,并且该方法使用了synchronized修饰。 

另外需要注意的是,一个线程可以从挂起状态变为可以运行状态(也就是被唤醒),即使该线程没有被其他线程调用notify()、notifyAll()方法进行通知,或者被中断,或者等待超时,这就是所谓的虚假唤醒。 

另外需要注意的是,当前线程调用共享变量的 wait()方法后只会释放当前共享变量上的锁,如果当前线程还持有其他共享变量的锁,则这些锁是不会被释放的。

package thread.wait;

public class WaitTest {
	private static volatile Object resourceA = new Object () ;
	private static volatile Object resourceB = new Object ();
	public static void main(String[] args) throws InterruptedException {
		
		Thread threadA = new Thread (new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					synchronized (resourceA) { 
						System.out.println("threadA get resourceA lock");
						synchronized (resourceB) { 
							System.out.println("threadA get resourceB lock" ) ;
							System.out.println("threadA release resourceA lock");
							resourceA .wait() ;
							}
					}
				}catch (InterruptedException e) {
					e.printStackTrace() ;
				} 
			}
		});
		Thread threadB = new Thread (new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					Thread .sleep(1000) ;
					synchronized (resourceA) { 
						System.out.println("threadB get resourceA lock");
						synchronized (resourceB) { 
							System.out.println("threadB get resourceB lock" ) ;
							System.out.println("threadB release resourceA lock");
							resourceA .wait() ;
							}
					}
				}catch (InterruptedException e) {
					e.printStackTrace() ;
				} 
			}
		});
		//启动线程
		threadA.start() ; 
		threadB.start() ; 
		//等待两个线程结束
		threadA.join() ; 
		threadB.join() ;
		
	}
}

 debug可以看到 走到下边40行不再往下走,说明resourceB还未被释放

wait(long timeout) 

该方法相比 wait()方法多了一个超时参数,它的不同之处在于,如果一个线程调用共享对象的该方法挂起后,没有在指定的timeout ms时间内被其他线程调用该共享变量的notify()或者notifyAll()方法唤醒,那么该方法还是会因为超时而返回。如果将timeout设置为0则和 wait方法效果一样,因为在 wait方法内部就是调用了wait(O)。需要注意的是,如果在调用该函数时,传递了一个负的timeout则会抛出IlegalArgumentException异常。

wait(long timeout, int nanos)

在其内部调用的是wait(long timeout)函数,如下代码只有在nanos>0时才使参数timeout递增1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心寒丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值