加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Java锁Synchronized之阻塞线程

(2014-10-17 14:52:16)
标签:

java

synchronized

阻塞

分类: Java进阶类

上一篇 Java锁Synchronized之锁比较

2.1     阻塞线程

2.4.1    线程状态及状态转换

当多个线程同时请求某个对象监视器时,对象监视器会设置几种状态用来区分请求的线程:

Contention List:所有请求锁的线程将被首先放置到该竞争队列

Entry ListContention List中那些有资格成为候选人的线程被移到Entry List

Wait Set:那些调用wait方法被阻塞的线程被放置到Wait Set

OnDeck任何时刻最多只能有一个线程正在竞争锁,该线程称为OnDeck

Owner:获得锁的线程称为Owner

!Owner:释放锁的线程。

下图反映了状态转换关系:

http://s16/mw690/003wfAbNzy6MSPsH4t19f&690

新请求锁的线程将首先被加入到ConetentionList中,当某个拥有锁的线程(Owner状态)调用unlock之后,如果发现EntryList为空则从ContentionList中移动线程到EntryList,下面说明下ContentionListEntryList的实现方式。

2.4.2    ContentionList虚拟队列

ContentionList并不是一个真正的Queue,而只是一个虚拟队列,原因在于ContentionList是由Node及其next指针逻辑构成,并不存在一个Queue的数据结构。ContentionList是一个后进先出(LIFO的队列,每次新加Node时都会在队头进行,通过CAS改变第一个节点的指针为新增节点,同时设置新增节点的next指向后续节点,而取得操作则发生在队尾。显然,该结构其实是个Lock-Free的队列。

因为只有Owner线程才能从队尾取元素,也即线程出列操作无争用,当然也就避免了CASABA问题。

http://s4/mw690/003wfAbNzy6MSPw4zYv33&690

2.4.3    EntryList

EntryListContentionList逻辑上同属等待队列ContentionList会被线程并发访问,为了降低对ContentionList队尾的争用,而建立EntryListOwner线程在unlock时会从ContentionList中迁移线程到EntryList,并会指定EntryList中的某个线程(一般为Head)为ReadyOnDeck)线程Owner线程并不是把锁传递给OnDeck线程,只是把竞争锁的权利交给OnDeckOnDeck线程需要重新竞争锁。这样做虽然牺牲了一定的公平性但极大的提高了整体吞吐量,在Hotspot中把OnDeck的选择行为称之为“竞争切换”。

OnDeck线程获得锁后即变为owner线程,无法获得锁则会依然留在EntryList,考虑到公平性,在EntryList中的位置不发生变化(依然在队头)。如果Owner线程被wait方法阻塞,则转移到WaitSet队列;如果在某个时刻被notify/notifyAll唤醒,则再次转移到EntryList

0

阅读 收藏 喜欢 打印举报/Report
后一篇:Java CAS
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有