【问题标题】:AtomicBitSet implementation for javajava的AtomicBitSet实现
【发布时间】:2012-09-14 12:31:38
【问题描述】:

标准 api 不包括 AtomicBitSet 实现。我可以在 AtomicIntegerArray 上滚动我自己的,但也不希望。

是否有人知道根据与 Apache 2 兼容的许可证发布的现有实现?我只需要基本操作来设置和检查位。

编辑:

代码对性能和内存都很关键,所以我想尽可能避免同步或每个标志的整数。

【问题讨论】:

  • 我认为同步的 BitSet 不是一个选项?如果你想要并发,你可以有一个包含 16 个的数组,这将允许多达 16 个线程一次访问它们。
  • 恕我直言,使用 AtomicIntegerArray 对于大多数(?)情况都是有意义的。为什么不使用它?
  • 当然,它不会像BitSet 那样可扩展。您需要使用读/写锁或类似的锁。
  • 代码有相当关键的性能和内存要求,所以我想尽可能避免使用锁或每个标志的整数。

标签: java concurrency


【解决方案1】:

我将使用 AtomicIntegerArray,并且每个整数使用 32 个标志,这将提供与 BitSet 相同的密度,但不需要线程安全锁。

public class AtomicBitSet {
    private final AtomicIntegerArray array;

    public AtomicBitSet(int length) {
        int intLength = (length + 31) >>> 5; // unsigned / 32
        array = new AtomicIntegerArray(intLength);
    }

    public void set(long n) {
        int bit = 1 << n;
        int idx = (int) (n >>> 5);
        while (true) {
            int num = array.get(idx);
            int num2 = num | bit;
            if (num == num2 || array.compareAndSet(idx, num, num2))
                return;
        }
    }

    public boolean get(long n) {
        int bit = 1 << n;
        int idx = (int) (n >>> 5);
        int num = array.get(idx);
        return (num & bit) != 0;
    }
}

【讨论】:

  • 如果它的性能至关重要,您可能希望避免并用位移位 (>>) 替换它。截至目前,JIT 无法猜测这些值只能是正数,并且不会自动优化。
  • @Durandal 好主意。改变它,这样你就可以拥有 640 亿位。
  • @PeterLawrey 在getset 中不应该int bit = 1 &lt;&lt; n;int bit = 1 &lt;&lt; ( n % 32 );
  • @tim_yates 在 Java 中,做这样的模数没有任何效果,因为移位是 &amp; 31 用于 int&amp; 63 很长。
  • 我不得不为一个项目开发一个 ThreadSafeBitSet,并添加了一些原子方法,如 compareAndSet 和 clearAndGetNextSetBit 方法。代码在这里gist.github.com/gomathi/322b8f3a3af54243383d
【解决方案2】:

http://www.javamex.com/tutorials/synchronization_concurrency_7_atomic_integer_long.shtml

不完全使用 BitSet,而是使用 AtomicInteger。

【讨论】:

    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 2012-06-03
    • 2012-09-04
    • 2020-10-24
    相关资源
    最近更新 更多