避免在Java循环中使用两个原子整数

避免在Java循环中使用两个原子整数,java,java-stream,java.util.concurrent,Java,Java Stream,Java.util.concurrent,我希望使用parallelStream读取/写入一个数组(并更新另一个数组),而不使用索引 AtomicInteger不允许按位操作,使用j.get()*2速度较慢: final int[]j={0}; ps.parallelStream().forEach(p->{ 长k=next[j[0]>>S]|=(1L S)]|=(1L>S)]|=(1L使用丑陋的ConcurrentHashMap解决,避免索引 next.replaceAll((p, k)->{ for(; k[0] &

我希望使用
parallelStream
读取/写入一个数组(并更新另一个数组),而不使用索引

AtomicInteger
不允许按位操作,使用
j.get()*2
速度较慢:

final int[]j={0};
ps.parallelStream().forEach(p->{

长k=next[j[0]>>S]|=(1L S)]|=(1L>S)]|=(1L使用丑陋的
ConcurrentHashMap解决,避免索引

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});
});

确实没有。你有问题吗?你似乎在以一种不安全的方式从多个线程中变异你的
j
数组。你在这里更新
next
,基于
j
的当前值……处理的顺序肯定会影响结果;那么你真的能并行地这样做吗?首先,我不明白“AtomicInteger不允许对该索引进行位操作”这句话是什么“该索引”在AtomicInteger的上下文中?如果您指的是AtomicInteger的值,那么它当然支持位操作。这并不重要,因为您从未使用位操作执行更新。您在
j[0]上执行的唯一更新
是一个普通的增量。因此,代码中没有任何内容阻止使用
AtomicInteger
替换单元素数组
j
。虽然这不太可能解决您的问题,因为您的代码取决于处理顺序。另一件值得一读的事情是:。您正在请求修复根本损坏的attempt使用外部计数器,而实际的解决方案是根本不使用外部计数器。这取决于
ps
实际上是什么。@ThomasKläger但当您假设一个非优化编译器时,您不会重复
j[0]当然有一个更有效的解决方案,但你总是无法描述你实际上在做什么。在你的问题代码中,你依赖于两个不同的数字,
p
参数,源自于
ps
是什么(无论出于什么原因,你仍然拒绝告诉我们),以及您试图通过外部计数器维护的数字。在您的地图解决方案中,这些数字似乎是相同的(地图键)。顺便说一句,您的地图没有“避免奇偶索引”,事实上,它是您唯一保留的(第一个版本为零/一,第二个版本为低/高)@Holger,由于
HashMap next
有一个长键,那么
p
是一个长键,而原始的
ps
是一个长键列表。如果我不清楚,很抱歉,我从不拒绝帮助。(这就是我继续搜索解决方案的原因)在我的回答中,我删除了外部计数器的使用
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
}