我们知道,在使用synchronized时,JVM会自动根据情况将我们的对象锁升级或降级,而wait和notify的使用场景一般情况下时多线程模式,也就是会出现竞争产生重量级锁。
一、用法
当我们的owner线程(当前获得到锁的线程不满足某些条件时,可以再锁对象中调用wait()方法将线程搁置,等到满足条件时用notify()方法将其唤醒)
Object obj = new Object();
synchronized (obj){
obj.wait();
}
//另一个线程
synchronized (obj){
obj.notify();
}
二、实现原理
我们知道重量级锁的实现是依赖于一个Monitor对象,也就是说将锁对象与Monitor关联
当我们调用wait()方法时,会使该线程(owner)进入waitset变为WAITING状态,同时解锁该锁对象。
举个例子来说,现在有好几家公司(线程)要在一个酒店开会,酒店仅有一个会议室(owner)和一个休息室(waitset),其中A公司的员工来了,占用会议室进行开会前准备(owner),但此时发现领导还没有来(条件缺失),于是A公司员工进入休息室等领导过来(进入waitset),会议室被B公司占用;当B公司开完会以后(调用notify),去叫A公司的人来使用会议室,A公司开会。
上面的离子简单类比了wait()和notify()方法,下面有几个注意事项:
1、调用notify方法并不意味着在waitset区的线程立即获得对象锁,而是进入阻塞队列继续同其他线程竞争。
2、由于waitset区可能会有多个线程,所以一次notify会随机唤醒其中一个线程。
3、如果想唤醒全部线程,可调用notifyall()方法。
三、sleep以及wait的区别
1、sleep是Thread方法,而wait是object方法。
2、sleep不需要强制和synchronized配合使用,但wait必须和synchronizedtongshishiyong。
3、sleep睡眠时保留对象锁,wait释放。