2016-11-22 68 views
0

我有多線程想在TreeSet<Long>中的一部分代碼中添加值。這些值幾乎是唯一的,因爲它們是System.nanoTime()。我定期清理TreeSet。問題是有時我的線程在TreeSet.add()函數中被阻塞。我用JConsole的觀看線程狀態,線程都處於RUNNABLE狀態和堆棧跟蹤顯示這一點:Java - 程序在TreeSet.add中陷入困境()

java.util.TreeMap.put(TeeMap.java:567) 
java.util.TreeSet.add(TreeSet.java:255) 
... //my program stack trace 

我使用的是JDK 1.7.0_60運行程序。另外我應該提到在這種情況下,CPU使用率成爲100%。我的問題是爲什麼線程被阻止,我該如何解決這種情況?我查看了TreeMap代碼,但我沒有發現問題,但我認爲問題涉及到TreeMap.put()中的while循環。

+1

什麼;我可以問一下嗎?你是否曾經同步對'TreeSet'的訪問? –

+0

@BoristheSpider不,它不是。這是問題嗎? – vakarami

+1

除非'Collection'被明確設計爲線程安全,否則不能被沒有內存障礙的多線程訪問。你創造的是一場數據競賽 - 祝賀你。 –

回答

1

正如在評論中提到的那樣,問題在於TreeSet不是線程安全的,如果我們想在多線程中修改它(添加或刪除數據),它必須在外部同步。

+0

或者,如果性能是一個問題(或者,即使不是這樣),也可以使用[ConcurrentSkipListSet](https://docs.oracle.com/javase/7/docs/) api/java/util/concurrent/ConcurrentSkipListSet.html)或['Collections.newSetFromMap(new ConcurrentHashMap <>())'](https://docs.oracle.com/javase/7/docs/api/java/util /Collections.html#newSetFromMap(java.util.Map))。 –

+0

令人驚訝的是,使用'Collections.newSetFromMap(new ConcurrentHashMap <>())'導致'ConcurrentModificationException'!最後我用'ConcurrentSkipListSet' – vakarami

+0

這個例外並不意味着你的想法。 –

相關問題