使用 java ConcurrentSkipListSet 添加方法时线程卡住
Thread stuck when use java ConcurrentSkipListSet add method
我正在使用 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
可能卡在别人身上了,另外comparator自定义排序数据的方法特别是相同(因为Set不支持相同的元素)而且Task
都是new instance,应该不会和别人冲突.
用jstack
cmd,主线程卡住了
at java.util.concurrent.ConcurrentSkipListMap.findPredecessor(ConcurrentSkipListMap.java:685)
这是一个错误还是我只是误导了一些原则?
感谢任何帮助或建议。
更新
我刚刚尝试将if (compare == 0) 1 else compare
修改为if (compare == 0) -1 else compare
,令人惊讶的是,我工作得很好!
有谁能解释一下它是如何工作的吗?源代码对我来说很难(我想很多人都同意我的看法),毕竟,jdk 做很多工作是为了机器执行速度而不是为了代码 reader。
终于
为了避免尴尬的情况,只需为 comparator
添加一些与 Set
语义匹配的不同因素,例如附加一个随机 value.But 我认为最好找到另一个真正合适的集合。
几天前,我发现一个好主意,当系统时间等于时,使用 hashCode 作为第二个验证。希望有帮助~
您的比较器不稳定。我不认为 ConcurrentSkipListMap
承诺在不同的调用给出不一致的结果时表现良好。例如,根据您的调用方式,您可以在代码中同时考虑 a < b 和 b < a。
我正在使用 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
可能卡在别人身上了,另外comparator自定义排序数据的方法特别是相同(因为Set不支持相同的元素)而且Task
都是new instance,应该不会和别人冲突.
用jstack
cmd,主线程卡住了
at java.util.concurrent.ConcurrentSkipListMap.findPredecessor(ConcurrentSkipListMap.java:685)
这是一个错误还是我只是误导了一些原则?
感谢任何帮助或建议。
更新
我刚刚尝试将if (compare == 0) 1 else compare
修改为if (compare == 0) -1 else compare
,令人惊讶的是,我工作得很好!
有谁能解释一下它是如何工作的吗?源代码对我来说很难(我想很多人都同意我的看法),毕竟,jdk 做很多工作是为了机器执行速度而不是为了代码 reader。
终于
为了避免尴尬的情况,只需为 comparator
添加一些与 Set
语义匹配的不同因素,例如附加一个随机 value.But 我认为最好找到另一个真正合适的集合。
几天前,我发现一个好主意,当系统时间等于时,使用 hashCode 作为第二个验证。希望有帮助~
您的比较器不稳定。我不认为 ConcurrentSkipListMap
承诺在不同的调用给出不一致的结果时表现良好。例如,根据您的调用方式,您可以在代码中同时考虑 a < b 和 b < a。