我正在使用ConcurrentSkipListSet集合來處理併發運算符。我發現它有時會卡住,使用此代碼reproduct:使用java時線程卡住ConcurrentSkipListSet添加方法
import java.util.Comparator
import java.util.concurrent._
object SetDeadLock extends App {
private val tasks = new ConcurrentSkipListSet[Task](new Comparator[Task](){
override def compare(o1: Task, o2: Task): Int = {
val compare = (o1.systemTime - o2.systemTime).toInt
if (compare == 0) 1 else compare //distinct same time task
}
})
for(i <- 1 to 20) {
tasks.add(Task())
println(s"added - $i")
}
case class Task() {
val systemTime = System.currentTimeMillis()
}
}
輸出
added - 1
added - 2
這也許停留在別人,除此之外,比較自定義排序數據的方法尤其是他們是一樣的(因爲設置不支持相同的元素),並且所有Task
都是新實例,不應與其他人衝突。
與jstack
CMD,主線程卡住
at java.util.concurrent.ConcurrentSkipListMap.findPredecessor(ConcurrentSkipListMap.java:685)
確實,這是一個錯誤或我只是誤導一些原則?
謝謝任何幫助或建議。
UPDATE
我剛纔試圖修改if (compare == 0) 1 else compare
到if (compare == 0) -1 else compare
,令人驚訝的,我工作得很好!
有沒有人可以澄清它是如何工作的?源代碼對我來說很難(我想很多人都同意我的觀點),畢竟,jdk爲機器執行速度做了很多工作,而不是代碼閱讀器。
最後
爲了避免尷尬的情況只是做出一些不同的因素comparator
其匹配Set
的語義,如附加一個隨機value.But我認爲它會更好找到另一個真正適合收藏。
幾天前,我發現一個好主意是當systemTime等於時,使用hashCode作爲第二次驗證。希望有幫助〜
可能是如此之快,以至於相同的時間結束,而比較器說相同的時間=不同。不知道它是如何實現的,但我可以想象這會導致一些醜陋的循環,因爲 zapl
@zapl,你是否意味着它是由'Comparator'引起的錯誤?睡500毫米也有問題 – LoranceChen