您的位置:首页 > 大数据 > 人工智能

wait/notify,sleep方法

2017-08-15 16:58 190 查看

wait/notify源码

wait是用来让线程等待的,并且释放锁。

notify是用来唤醒等待线程的,执行完后,在同一同步队列中的等待线程开始抢占锁。

监视器: monitor

锁: lock(JVM里只有一种独占方式的lock)

进入监视器: monitorenter

离开/释放监视器: monitorexit

(monitorenter和monitorexit是JVM的指令)

拥有者: owner

通过synchronized来完成的,使用了
monitorenter
指令和
monitorexit
指令

monitor使用了ObjectMonitor来实现。

JAVA程序中每一个监视区域都和一个对象引用相关联。

锁住一个对象相当于获得对象相关联的监视器

这里的监视器可以比喻成一个房间,进入房间相当于进入监视器,占据房间相当于持有监视器,离开房间相当于释放监视器。



每个线程都有ObjectMonitor 的free和used的objectMonitor对象列表,如果没有free objectMonitor对象列表,将向global 中ListLock Allocate为了提高效率

在上图中可以看见成员里头有2个队列:_WaitSet和_EntryList(保存ObjectWaiter对象列表);_owner执向获得ObjectMonitor对象的线程。看图



_WaitSet :处于wait状态的线程,会被加入到wait set;

_EntryList:处于等待锁block状态的线程,会被加入到entry set;

ObjectWaiter对象是双向链表结构,保存了_thread(当前线程)以及当前的状态TState等数据, 每个等待锁的线程都会被封装成ObjectWaiter对象,然后加入不同的队列中去。

wait方法实现

将当前线程封装成
ObjectWaiter
对象
->node


通过
ObjectMonitor :: AddWaiter
方法将node添加到
_WaitSet
列表中;

通过
ObjectMonitor :: exit
方法释放当前的
ObjectMonitor
对象,这样其它竞争线程就可以获取该
ObjectMonitor
对象。

最终底层的park方法会挂起线程。

notify方法实现

如果当前
_WaitSet
为空,即没有正在等待的线程,则直接返回;

通过
ObjectMonitor :: DequeueWaiter
方法,获取
_WaitSet
列表中的第一个
ObjectWaiter
节点,实现很简单。

notifyAll方法实现

跟notify差不多,就是第二步直接用for循环取出所有的
_WaitSet
中的节点。



对于java中的sleep实现

我想,应该是和LinuxC下的sleep类似的。。。肯定不一样

通过底层alarm设定闹钟,闹钟会发信号给这个线程。 sleep是不会释放锁的。

sleep是Thread中的静态方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程
相关文章推荐