2016-02-26 88 views
0

ReentrantReadWriteLock如何工作?它是自旋锁吗?是否将ReentrantReadWriteLock实现为自旋锁?

的问题来自Elasticsearch,当它显示

java.lang.ThreadLocal$ThreadLocalMap.expungeStaleEntry(Unknown Source) 
    java.lang.ThreadLocal$ThreadLocalMap.remove(Unknown Source) 
    java.lang.ThreadLocal$ThreadLocalMap.access$200(Unknown Source) 
    java.lang.ThreadLocal.remove(Unknown Source) 
    java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(Unknown Source) 
    java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(Unknown Source) 
    java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(Unknown Source) 
热线程

中的所有快照和CPU占用率高的同时。它看起来像旋转锁。

回答

0

与线程本地数据相关的成本。你在这里看到的就是这个。你甚至可以看到的ReentrantReadWriteLock评论mentionning这一点,并通过缓存线程本地数据的数据对其进行优化:

评论:

/** 
    * The hold count of the last thread to successfully acquire 
    * readLock. This saves ThreadLocal lookup in the common case 
    * where the next thread to release is the last one to 
    * acquire. 
    * [...] 
    */ 
    private transient HoldCounter cachedHoldCounter; 

的ReentrantReadWriteLock不使用自旋锁。它使用来自AbstractQueueSynchronizer的使用wait/notify(由LockSupport.park(this)实现)的Sync对象。

+1

谢谢你的回答!是的,我看到了它......但有些人公然声称,当他们在我的问题中看到这样的堆栈跟踪时,问题出现在自旋锁定中。我在'ThreadLocal'中制作了'ReentrantReadWriteLock'副本,但是我没有时间去测试,因为改变GC已经解决了我们的问题,这听起来很奇怪...... – cybersoft

+0

你介意不用在ThreadLocal中保存计数器?我可能会用它来解决另一个我们正在努力解决的问题。 –

+0

它没有任何困难:http://pastebin.com/jXVyk1Db但它可能不起作用,因为这些保持计数器上有一些逻辑。代码与此仅被注释掉,你可以看 – cybersoft