wait/notify原理详解

我们知道,在使用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释放。

上一篇:POSIX 网络API原理


下一篇:浅谈Java中线程的生命周期