📜  jdk 中的 concurrentskiplistset 无限循环 - Java (1)

📅  最后修改于: 2023-12-03 14:43:05.671000             🧑  作者: Mango

JDK 中的 ConcurrentSkipListSet 无限循环

ConcurrentSkipListSet 是 JDK 提供的一种线程安全的有序集合,它使用 Skip List 实现。然而,有时候在使用 ConcurrentSkipListSet 的时候,可能会遇到无限循环的问题。

问题表现

当我们使用 ConcurrentSkipListSet 遇到无限循环的时候,程序会进入一个死循环的状态,CPU 占用率会飙升,导致程序最终崩溃。

问题原因

造成无限循环的原因,是因为 ConcurrentSkipListSet 的实现中,对比节点大小的时候,使用了 compareTo() 方法。如果两个节点的值相同,但是 compareTo() 方法返回的结果不同,就会发生死循环的问题。

这是因为在判断两个节点大小时,如果 compareTo() 返回的结果不是 0,就会一直比较下去,从而导致无限循环。

解决方法

为了避免 ConcurrentSkipListSet 出现无限循环的问题,我们需要确保 compareTo() 方法逻辑上是一致的。具体的做法是,我们需要重写 compareTo() 方法,确保对于相同值的节点,它们的 compareTo() 返回值是相等的。

public class MyObject implements Comparable<MyObject>{
    private int value;
    // 省略其它代码

    // 重写 compareTo 方法。
    @Override
    public int compareTo(MyObject o) {
        if (this.value == o.value) {
            return 0;
        }
        return this.value < o.value ? -1 : 1;
    }
}

在上面的代码中,我们重写了 compareTo() 方法,确保对于两个 MyObject 实例,如果它们的 value 值相同,那么 compareTo() 方法返回值应该是相等的。

这样,在使用 ConcurrentSkipListSet 的时候,就可以避免无限循环的问题了。

总结

在使用 ConcurrentSkipListSet 的时候,出现无限循环是一个比较难以发现和排查的问题。如果你遇到了这个问题,可以考虑重写 compareTo() 方法,确保对于相同值的节点,它们的 compareTo() 返回值是相等的。