wait()和notify()以及notifyAll()方法简述

本文详细解析了Java中线程间的通信机制,包括wait(), notify()和notifyAll()方法的使用,以及它们在同步代码块中的作用。文章通过实例演示了如何在多线程环境中正确使用这些方法,以实现线程之间的有效通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wait()和notify()以及notifyAll()方法

wait()使当前线程进入等待队列,并释放该线程所拥有的锁,(而sleep()方法挂起当前线程,并不释放该线程所拥有的锁),等待某个条件发生变化,再由其他线程唤醒(notify)。
wait()方法可以有一个参数,即等待的最长时间,若等待时长超过最长时间,该线程会从wait()中恢复执行。
notify()用来唤醒由wait()引起的被挂起的线程,当一个线程调用notify()时,在众多等待同一个锁的任务中只有一个会被唤醒。notifyAll()将唤醒所有等待当前线程所拥有的锁的线程,但只有一个被唤醒的线程获得锁。
实际上,只能在同步代码块中调用wait(),nofity()和notifyAll(),因为这些方法都操作锁。如果不在同步代码块中调用这些方法,程序能通过编译,但在运行的时候,会得到IllegalMonitorStateExceptiion异常。
这三个方法是基类Object的一部分,而不是Thread的一部分。因为这些方法操作的锁也是所有对象的一部分。
当一个线程调用notifyAll()方法时,并不会立即释放锁,只有在同步代码块语句执行完后,才释放锁。代码演示如下:

class NotifyDest{
	public synchronized void f() {
		System.out.println("f()");
		notifyAll();//唤醒等待该锁的所有线程
		System.out.println("exit");
	}
	public synchronized void g() {
		try {
			wait();//挂起当前线程,并释放锁
			System.out.println("g()");
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}
class Manager {
	static NotifyDest notifyDest = new NotifyDest();
	
}
class Manager1 extends Manager implements Runnable{
	public void run() {
		notifyDest.f();
	}
}
class Manager2 extends Manager implements Runnable{
	public void run() {
		notifyDest.g();
	}
}
public class NotifyDemo {
	public static void main(String[] args) throws Exception {
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new Manager2());
		TimeUnit.SECONDS.sleep(1);
		exec.execute(new Manager1());
		TimeUnit.SECONDS.sleep(1);
		System.out.println("main()");
	}
}
运行结果:
f()
exit
g()
main()

由运行结果可知,System.out.println(“exit”)语句在notifyAll()语句之后,但它执行了,说明线程调用notify()方法时,并没有立即释放锁并结束当前线程

注意:你必须用一个检查感兴趣的条件的while循环包围wait()。原因如下:

(1)你可能有多个任务出于相同的原因(即进入wait状态的条件一致)在等待同一个锁,而首先被唤醒任务可能会改变这个条件,那么这个任务应该被再次挂起,直至其感兴趣的条件发生变化。
(2)在这个任务从其wait()中被唤醒的时刻,有可能会有某个其他的任务已经做出了改变,而使得这个任务在此时不能执行。此时,应该通过再次调用wait()来将其重新挂起。
(3)也有可能某些任务出于不同的原因在等待你的对象上的锁(在这种情况下必须使用notifyAll())。在这种情况下,你需要检查是否已经由正确的原因唤醒,如果不是,就再次调用wait()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值