【多线程整理 4】notify与notifyAll

notify()

        一个线程调用共享对象的notify)方法后,会唤醒一个在该共享变量上调用wait系列方法后被挂起的线程。一个共享变量上可能会有多个线程在等待,具体唤醒哪个等待的线程是随机的。

        此外,被唤醒的线程不能马上从 wait方法返回并继续执行,它必须在获取了共享对象的监视器锁后才可以返回,也就是唤醒它的线程释放了共享变量上的监视器锁后,被唤醒的线程也不一定会获取到共享对象的监视器锁,这是因为该线程还需要和其他线程一起竞争该锁,只有该线程竞争到了共享变量的监视器锁后才可以继续执行。

        类似wait系列方法,只有当前线程获取到了共享变量的监视器锁后,才可以调用共享变量的notify()方法,否则会抛出IllegalMonitorStateException异常。

notifyAll()

不同于在共享变量上调用notify()函数会唤醒被阻塞到该共享变量上的一个线程,notifyAll()方法则会唤醒所有在该共享变量上由于调用wait系列方法而被挂起的线程。

package thread.notify;

public class NotifyTest {
	private static volatile Object resourceA = 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
					//获取resourceA共享资源的监视器锁
					synchronized (resourceA) { 
						System.out.println("threadA get resourceA lock");
						try {
							System.out.println("threadA begin wait" ) ;
							resourceA.wait() ;
							System.out.println("threadA end wait" ) ;
					}catch (InterruptedException e) {
						e.printStackTrace() ;
					} 
				}
			}
		});
		Thread threadB = new Thread (new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
					//获取resourceA共享资源的监视器锁
					synchronized (resourceA) { 
						System.out.println("threadB get resourceA lock");
						try {
							System.out.println("threadB begin wait" ) ;
							resourceA.wait() ;
							System.out.println("threadB end wait" ) ;
					}catch (InterruptedException e) {
						e.printStackTrace() ;
					} 
				}
			}
		});
		Thread threadC = new Thread (new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
					//获取resourceA共享资源的监视器锁
					synchronized (resourceA) { 
						System.out.println("threadC begin notify");
						resourceA.notify();
						//resourceA.notifyAll();
				}
			}
		});
		threadA.start() ; 
		threadB.start() ; 
		Thread.sleep(1000);
		threadC.start () ;
		
	}
	

}

使用notify结果如下: 

 

 使用notifyAll结果如下:

需要注意的地方是,在共享变量上调用notifyAll()方法只会唤醒调用这个方法前调用了wait系列函数而被放入共享变量等待集合里面的线程。如果调用notifyAll()方法后一个线程调用了该共享变量的wait()方法而被放入阻塞集合,则该线程是不会被唤醒的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心寒丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值