[Java] 线程之wait和notify

wait方法和notify方法来源于Object类,对wait方法的调用必须先获得监视器,然后在监视器上调用wait方法,意思是使当前线程在监视器上等待(即进入阻塞状态),直到被其它线程在同一个监视器上通知为止,然后解除阻塞状态,重新被安排调度执行,否则将一直阻塞。wait方法还有重载方法,即带有超时参数,表示该线程最大的等待时间,过了这个时间后,即便是没有其他线的通知,该线程也会自动解除阻塞状态,重新被安排调度执行。执行完wait后,监视器就会被释放掉,以供其它线程获得该监视器。

对notify方法的调用必须先获得监视器,然后在监视器上调用notify方法,意思是从之前在该监视器上等待的所有线程中解除一个线程,使它重新被安排调度执行,至于究竟解除的是等待线程中的哪一个,由系统决定,是随机的,并没有什么顺序。而且被解除的线程在重新被调度方面也不享有任何特权。还有一个相似的notifyAll方法,也必须先获得监视器,然后在监视器上调用notifyAll方法,意思是把之前在该监视器上等待的所有线程全部解除,使它们重新被安排调度执行,执行哪个被先调度执行,也是随机的,由系统决定。这些被解除的线程之间都是平等的,谁也没有任何特权。执行完notify或notifyAll后,监视器就会被释放掉,以供其它线程获得该监视器。

下面是简单的示例代码:

final Object monitor = new Object();
		final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Thread t1 = new Thread(new Runnable(){
			@Override
			public void run() {
					System.out.println("线程1等待锁:" + sdf.format(new Date()));
				synchronized(monitor) {
					System.out.println("线程1获得锁:" + sdf.format(new Date()));
					try {
						System.out.println("线程1 wait:" + sdf.format(new Date()));
						monitor.wait();
						System.out.println("线程1获得锁:" + sdf.format(new Date()));
						System.out.println("线程1 wait over:" + sdf.format(new Date()));
						System.out.println("线程1 notify:" + sdf.format(new Date()));
						monitor.notify();
					} catch (InterruptedException e) {
						
					}
				}
			}});
		
		Thread t2 = new Thread(new Runnable(){
			@Override
			public void run() {
					System.out.println("线程2等待锁:" + sdf.format(new Date()));
				synchronized(monitor) {
					System.out.println("线程2获得锁:" + sdf.format(new Date()));
					try {
						System.out.println("线程2 wait:" + sdf.format(new Date()));
						monitor.wait();
						System.out.println("线程2获得锁:" + sdf.format(new Date()));
						System.out.println("线程2 wait over:" + sdf.format(new Date()));
						System.out.println("线程2 notify:" + sdf.format(new Date()));
						monitor.notify();
					} catch (InterruptedException e) {
						
					}
				}
			}});
		
		Thread t3 = new Thread(new Runnable(){
			@Override
			public void run() {
					System.out.println("线程3等待锁:" + sdf.format(new Date()));
				synchronized(monitor) {
					System.out.println("线程3获得锁:" + sdf.format(new Date()));
					try {
						System.out.println("线程3 wait:" + sdf.format(new Date()));
						monitor.wait();
						System.out.println("线程3获得锁:" + sdf.format(new Date()));
						System.out.println("线程3 wait over:" + sdf.format(new Date()));
						System.out.println("线程3 notify:" + sdf.format(new Date()));
						monitor.notify();
					} catch (InterruptedException e) {
						
					}
				}
			}});
		
		Thread t4 = new Thread(new Runnable(){
			@Override
			public void run() {
					System.out.println("线程4等待锁:" + sdf.format(new Date()));
				synchronized(monitor) {
					System.out.println("线程4获得锁:" + sdf.format(new Date()));
					try {
						System.out.println("线程4 wait:" + sdf.format(new Date()));
						monitor.wait();
						System.out.println("线程4获得锁:" + sdf.format(new Date()));
						System.out.println("线程4 wait over:" + sdf.format(new Date()));
						System.out.println("线程4 notify:" + sdf.format(new Date()));
						monitor.notify();
					} catch (InterruptedException e) {
						
					}
				}
			}});
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		Thread.sleep(2000);
		synchronized(monitor) {
			System.out.println("主线程 notify:" + sdf.format(new Date()));
			monitor.notify();
		}

下面是执行结果:

线程1等待锁:2012-11-04 15:05:32
线程1获得锁:2012-11-04 15:05:32
线程1 wait:2012-11-04 15:05:32
线程3等待锁:2012-11-04 15:05:32
线程3获得锁:2012-11-04 15:05:32
线程3 wait:2012-11-04 15:05:32
线程2等待锁:2012-11-04 15:05:32
线程2获得锁:2012-11-04 15:05:32
线程2 wait:2012-11-04 15:05:32
线程4等待锁:2012-11-04 15:05:32
线程4获得锁:2012-11-04 15:05:32
线程4 wait:2012-11-04 15:05:32
主线程 notify:2012-11-04 15:05:34
线程1获得锁:2012-11-04 15:05:34
线程1 wait over:2012-11-04 15:05:34
线程1 notify:2012-11-04 15:05:34
线程3获得锁:2012-11-04 15:05:34
线程3 wait over:2012-11-04 15:05:34
线程3 notify:2012-11-04 15:05:34
线程2获得锁:2012-11-04 15:05:34
线程2 wait over:2012-11-04 15:05:34
线程2 notify:2012-11-04 15:05:34
线程4获得锁:2012-11-04 15:05:34
线程4 wait over:2012-11-04 15:05:34
线程4 notify:2012-11-04 15:05:34

从执行结果可以看出每个线程执行完wait后就释放了锁,然后其它线程获得锁,执行wait,直到四个线程都执行了wait并进入了等待,主线程休眠了两秒后,获得了锁并执行了notify方法,通知一个线程解除,然后主线程释放了锁。线程1比较幸运,它被通知到了,然后重新获得了锁,阻塞被解除,它又执行了notify方法,然后释放了锁。剩余的三个线程将有一个被通知,这次是线程3,重复这样的过程,直到四个线程都被解除完。这就是线程的等待和通知机制。

如文章有错误之处,敬请之处,共同讨论!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值