避免在循环中使用两个 AtomicInteger Java

Avoiding usage of two AtomicInteger in a loop Java

我希望 read/write 一个数组(并更新另一个数组)parallelStream,没有索引。

AtomicInteger不允许按位运算,使用j.get() * 2很慢:

final int[] j = {0};
ps.parallelStream().forEach(p -> {
    long k = next[j[0] << 1];                       
    for(; k < finalK; k += p)
        seg[(int) (k >>> S)] |= (1L << (k & BMASK));
    next[j[0] << 1] = (k - finalK);

    k = next[j[0] << 1 | 1];                        
    for(; k < finalK; k+= p) 
        seg[(int) (k >>> S)] |= (1L << (k & BMASK));
    next[j[0] << 1 | 1] = (k - finalK);
    j[0]++;
});

这是在顺序流中工作,而不是并行。

抱歉,如果 seg[(int) (k >>> S)] |= (1L << (k & BMASK)); 看起来不可读,这与设置 BitSet 的位 k 相同(seg 是一个 long[]),这对我来说太慢了。

使用丑陋的 ConcurrentHashMap<Long, Long[]> 避免索引

解决
next.replaceAll((p, k)->{

    for(; k[0] < finalK; k[0] += p)
        seg[(int) (k[0] >>> S)] |= (1L << (k[0] & BMASK));

    for(; k[1] < finalK; k[1] += p)                         
        seg[(int) (k[1] >>> S)] |= (1L << (k[1] & BMASK));

    return new long[]{k[0]-finalK, k[1]-finalK});
});

但这很慢,而且会占用更多内存

编辑
为了清楚起见,我使用了一些 indexPairs class 而不是数组和 BitSet 改进了一些东西

ConcurrentHashMap<Long, indexPairs> next = initNext();
BitSet segment = new BitSet();
while(condition) {
    next.replaceAll((p, k) -> {
        for (; k.low < finalK; k.low += p)
            segment.set(k.low);
        k.low -= finalK;
        for (; k.high < finalK; k.high += p)                 
            segment.set(k.high);
        k.high -= finalK;
        return k;
    });
    ... Do something with segment
}