有沒有辦法告訴Java對象,哪個線程(或null)當前擁有它的監視器?或者至少有一種方法來判斷當前線程是否擁有它?確定哪個線程擁有監視器
回答
我已經找到了一些自己的答案。要測試當前線程是否支持顯示器,請使用Thread.holdsLock
!
if (!Thread.holdsLock(data)) {
throw new RuntimeException(); // complain
}
這真的很快(亞微秒),並且從1.4開始就可用。
要測試一般情況下哪個線程(或線程ID)持有鎖,可以使用java.lang.management
類(謝謝@amicngh)來執行此操作。
public static long getMonitorOwner(Object obj) {
if (Thread.holdsLock(obj)) return Thread.currentThread().getId();
for (java.lang.management.ThreadInfo ti :
java.lang.management.ManagementFactory.getThreadMXBean()
.dumpAllThreads(true, false)) {
for (java.lang.management.MonitorInfo mi : ti.getLockedMonitors()) {
if (mi.getIdentityHashCode() == System.identityHashCode(obj)) {
return ti.getThreadId();
}
}
}
return 0;
}
有跟這個有幾個注意事項:
- 這是一個有點慢(〜½毫秒在我的情況大概與線程的數量線性增加)。
- 它需要Java 1.6和一個虛擬機
ThreadMXBean.isObjectMonitorUsageSupported()
爲真,因此它的便攜性較差。 - 它需要「監視器」安全權限,因此可能不適用於沙盒applet。
- 如果需要,將線程ID轉換爲線程對象,這有點不重要,因爲我想你必須使用Thread.enumerate,然後循環找出哪一個具有ID,但是這具有理論上的競爭條件,因爲當你調用枚舉時,該線程可能不再存在,或者可能出現了具有相同ID的新線程。
但是,如果您只想測試當前線程,Thread.holdsLock
工作得很好!否則,java.util.concurrent.locks.Lock
的實現可能比普通的Java監視器提供更多的信息和靈活性(謝謝@ user1252434)。
java類監視器是JVM的內部,你不能真正玩它。
如果您知道該對象被鎖定,您可以嘗試再次獲取監視器 - 如果能夠得到它,這意味着您正在鎖定線程中的對象(因爲java鎖是遞歸的 - 您可以鎖定兩次來自同一個線程)。 問題是你不能嘗試來同步。
您可以使用不安全的對象來做到這一點。 不安全有一個tryMonintorEnter()
方法可以做到這一點。見unsafe。
不安全也許能助您獲得持有監視器的線程,但我不知道該怎麼做......
在的Java 1.6你可以使用反射來得到這個信息。
ThreadMXBean tBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfo = tBean .getThreadInfo(bean.getAllThreadIds(), true, true);
而不是使用的,你可能想看看ReentrantLock,尤其是它的方法getOwner()
和isHeldByCurrentThread()
。然而,使用它需要更多的訓練,因爲您明確地必須unlock()
它,最好是在finally
塊。
我對RentrantLock並不熟悉。雖然這不是我的問題,但我認爲它對我的用例來說更好,因爲我可以在類C中進行鎖定並保持通話之間的鎖定。非常感謝。 – Boann
如果你喜歡,你可以保留你的鎖定邏輯。使用ReentrantLock所需的唯一更改是從'synchronized(myLock){..}'到'myLock.lock();嘗試{..}終於{myLock.unlock();}'。雖然,與同步不同,鎖不能只是任何對象。 – user1252434
- 1. Java中的監視器和同步塊(看起來兩個線程同時擁有一個監視器)
- 2. Mac OS編程和GDB:確定哪個線程擁有一個NSRecursiveLock
- 3. 鎖定/多線程監視器
- 4. 如何查看哪個監視器是等待的線程?
- 5. 如何確定哪個監視器發生Swing鼠標事件?
- 6. 線程等待監視器
- 7. 怎麼可能,3個線程處於阻塞狀態,等待相同的監視器,並且沒有線程擁有該監視器
- 8. 監視線程
- 9. 如何確定哪個UIView超級視圖導致子視圖擁有userInteractionEnabled = NO?
- 10. 如何使用進程監視器來確定哪個DLL導致BadImageFormatException
- 11. 如何確定我的.NET Windows Forms程序運行在哪個監視器上?
- 12. 確定連接了哪些監視器/顯示器/屏幕
- 13. 如何從監視器中斷另一個線程線程
- 14. 如何確定完成哪個線程
- 15. 線程監視C#
- 16. .net線程監視
- 17. 監視.NET線程
- 18. 編程監視器定位
- 19. 如何確定從另一個線程創建哪個線程?
- 20. 以編程方式確定哪個Java線程持有鎖
- 21. 監視哪個線程正在下載url
- 22. pthread_cond_broadcast之後哪個線程擁有關聯的互斥鎖?
- 23. 如何確定一個shiro用戶擁有哪些權限
- 24. 如何確定我擁有哪個iOS SDK?
- 25. java線程中的「監視器」
- 26. C#線程同步監視器+ ResetEvent
- 27. c#中的線程監視器類#
- 28. Java監視器和線程併發性
- 29. 如何查看哪個監視器是通過API等待的線程?
- 30. Java線程監視其他線程
您可以通過線程轉儲獲取此信息 – fge