gpt4 book ai didi

java - 使用java ConcurrentSkipListSet add方法时线程卡住

转载 作者:行者123 更新时间:2023-12-01 09:51:39 25 4
gpt4 key购买 nike

我正在使用 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

它可能卡在其他地方,此外,比较器自定义排序数据方法特别是它们是相同的(因为Set不支持相同元素)并且所有Task都是新实例,它不应该与其他。

使用jstack cmd,主线程卡住

at java.util.concurrent.ConcurrentSkipListMap.findPredecessor(ConcurrentSkipListMap.java:685)

这是一个错误还是我只是误导了一些原则?

感谢任何帮助或建议。

更新
我刚刚尝试将 if (compare == 0) 1 else Compare 修改为 if (compare == 0) -1 else Compare,令人惊讶的是,我工作得很好!

有谁能解释一下它是如何工作的吗?源代码对我来说很难(我想很多人都同意我的观点),毕竟jdk为机器执行速度而不是代码阅读器做了很多工作。

终于
为了避免尴尬的情况,只需对 comparator 做一些不同的因素来匹配 Set 的语义,例如附加一个随机值。但我认为最好找到另一个真实的值适合 Collection 。

几天前,我发现一个好主意,当 systemTime 等于时,使用 hashCode 作为第二次验证。希望有帮助~

最佳答案

您的比较器不稳定。我认为当不同的调用给出不一致的结果时,ConcurrentSkipListMap 不会表现得很好。例如,根据您的调用方式,您可以在代码中同时考虑 a < b 和 b < a。

关于java - 使用java ConcurrentSkipListSet add方法时线程卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37558703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com