标签: atomicinteger

AtomicInteger.updateAndGet()和AtomicInteger.accumulateAndGet()之间是否存在任何功能差异?

是否存在AtomicInteger.accumulateAndGet()无法替换的场景AtomicInteger.updateAndGet(),或者仅仅是方法引用的便利?

这是一个简单的例子,我没有看到任何功能差异:

AtomicInteger i = new AtomicInteger();
i.accumulateAndGet(5, Math::max);
i.updateAndGet(x -> Math.max(x, 5));
Run Code Online (Sandbox Code Playgroud)

显然,同样也适用于getAndUpdate()getAndAccumulate().

java lambda atomic java-8 atomicinteger

13
推荐指数
1
解决办法
5151
查看次数

如何根据条件更新Atomic?

如何更新AtomicInteger当前值是否小于给定值?这个想法是:

AtomicInteger ai = new AtomicInteger(0);
...
ai.update(threadInt); // this call happens concurrently
...
// inside AtomicInteger atomic operation
synchronized {
    if (ai.currentvalue < threadInt)
        ai.currentvalue = threadInt;
}
Run Code Online (Sandbox Code Playgroud)

java concurrentmodification atomicinteger

11
推荐指数
2
解决办法
2862
查看次数

for循环的每个循环都是原子操作吗?

incrementAndGet以下 AtomicBigInteger 实现的方法是原子操作吗?我特别想知道这for (; ; )部分。JVM 是否以某种方式保证 for 循环中的每个循环都是原子执行的?

public final class AtomicBigInteger {

    private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>();

    public AtomicBigInteger(BigInteger bigInteger) {
        valueHolder.set(bigInteger);
    }

    public BigInteger incrementAndGet() {
        for (; ; ) {
            BigInteger current = valueHolder.get();
            BigInteger next = current.add(BigInteger.ONE);
            if (valueHolder.compareAndSet(current, next)) {
                return next;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我从这里得到了这段代码: Maybe to secureincrement BigInteger in a thread safe way, 也许使用 AtomicReference, w/olocking? 然而,这种实现正在广泛传播,您可以在互联网上的许多不同地方找到它。

java atomic atomicinteger

10
推荐指数
2
解决办法
737
查看次数

如果对int变量的写入和读取是原子的,为什么需要AtomicInteger?

我在Oracle文档中读过:

  • 读取和写入对于引用变量和大多数 原始变量(除long和double之外的所有类型)都是原子的.

(我想这个功能已经在一些新的JDK版本中添加了,因为我曾经认为所有原始变量的读/写都不是原子的)

这是否意味着AtomicInteger已弃用且不应在新项目中使用?

java multithreading atomic atomicinteger

8
推荐指数
3
解决办法
899
查看次数

多线程中的AtomicInteger

我想找到从0到1000000的所有素数.为此我写了愚蠢的方法:

public static boolean isPrime(int n) {
    for(int i = 2; i < n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

它对我有好处,不需要编辑.比我写下一个代码:

private static ExecutorService executor = Executors.newFixedThreadPool(10);
private static AtomicInteger counter = new AtomicInteger(0);
private static AtomicInteger numbers = new AtomicInteger(0);

public static void main(String args[]) {
    long start = System.currentTimeMillis();
    while (numbers.get() < 1000000) {
        final int number = numbers.getAndIncrement();  // (1) - fast
        executor.submit(new Runnable() {
            @Override
            public …
Run Code Online (Sandbox Code Playgroud)

java multithreading atomicinteger

7
推荐指数
2
解决办法
1668
查看次数

原子整数的compareandexchange()与compareandset()

在研究 AtomicInteger 时,我发现这个 API 提供了两种方法。

比较和交换

如果当前值(称为见证值)==预期值,则以原子方式将该值设置为 newValue,并具有由以下指定的记忆效应VarHandle.compareAndExchange(java.lang.Object...)

比较并设置

以原子方式将该值设置为newValue当前值value == expectedValue,并具有由 指定的记忆效应 VarHandle.compareAndSet(java.lang.Object...)

我无法理解两者之间的区别,请帮助提供合适的例子。

java atomic compare-and-swap atomicinteger java-9

7
推荐指数
1
解决办法
3441
查看次数

为什么不建议使用基于AtomicInteger的Stream解决方案?

说我有这个水果清单: -

List<String> f = Arrays.asList("Banana", "Apple", "Grape", "Orange", "Kiwi");
Run Code Online (Sandbox Code Playgroud)

我需要在每个水果前面加一个序列号并打印出来.水果或序列号的顺序无关紧要.所以这是一个有效的输出: -

4. Kiwi
3. Orange
1. Grape
2. Apple
5. Banana
Run Code Online (Sandbox Code Playgroud)

解决方案#1

AtomicInteger number = new AtomicInteger(0);

String result = f.parallelStream()
        .map(i -> String.format("%d. %s", number.incrementAndGet(), i))
        .collect(Collectors.joining("\n"));
Run Code Online (Sandbox Code Playgroud)

解决方案#2

String result = IntStream.rangeClosed(1, f.size())
        .parallel()
        .mapToObj(i -> String.format("%d. %s", i, f.get(i - 1)))
        .collect(Collectors.joining("\n"));
Run Code Online (Sandbox Code Playgroud)

为什么解决方案#1是一种不好的做法?我在很多地方已经看到AtomicInteger基础解决方案很糟糕(比如在这个答案中),特别是在并行流处理中(这就是我使用上面的并行流来尝试遇到问题的原因).

我查看了这些问题/答案: -
在哪些情况下,Stream操作应该是有状态的?
使用AtomicInteger在Stream中进行索引是一种合法的方式吗?
Java 8:计算lambda迭代的首选方法?

他们只是提到(除非我错过了什么)"可能会出现意想不到的结果".像什么?它可以在这个例子中发生吗?如果没有,你能为我提供一个可能发生的例子吗?

至于" 不保证应用映射器函数的顺序 ",那么这就是并行处理的本质,所以我接受它,而且,在这个特定的例子中,顺序无关紧要.

AtomicInteger 是线程安全的,所以它不应该是并行处理的问题.

有人可以提供使用这种基于状态的解决方案时会出现问题的示例吗?

java thread-safety java-8 java-stream atomicinteger

6
推荐指数
1
解决办法
270
查看次数

AtomicInteger.compareAndSet 返回原始值,而不是布尔值

Java 的AtomicInteger优惠public final boolean compareAndSet(int expect, int update)。如果false返回,我想知道比较失败时的实际值是多少。这在Java中可能吗?

在 .Net 中,有public static int CompareExchange(ref int location1, int value, int comparand), 总是返回原始值。

java atomic compare-and-swap atomicinteger

5
推荐指数
1
解决办法
806
查看次数

AtomicInteger 和比较操作

我正在尝试使用 AtomicInteger 变量作为锁。因此,想知道下面发布的代码是否是线程安全的。我知道incrementAndGet()是一个原子操作。但是,我不确定后续的 '==' 操作是否也将是原子的(如果在我进行比较时该值增加到 2,该怎么办。)。所以发布这个问题来听听你的想法。

private AtomicInteger count = new AtomicInteger(0); //Shared variable
private final int max = 1;

if(count.incrementAndGet() == max) {
  //Do something
}
Run Code Online (Sandbox Code Playgroud)

java multithreading atomicinteger

5
推荐指数
1
解决办法
3819
查看次数

初始化atomic_flag

我有一个struct,叫它struct foo,我想在上面添加一个atomic_flag变量。到目前为止,我一直在研究calloc该结构,因为它主要需要零初始化。我应该如何初始化atomic_flag成员?

struct foo{
    //...
    atomic_flag a_flg;
    //...
};
struct foo *foop = calloc(1,sizeof *foop);
if(!foop) return -1;

//should I be giving up `calloc` (/`malloc`+`memset`) in favor of `malloc`+this?
*foop = (struct foo){ ATOMIC_FLAG_INIT };
Run Code Online (Sandbox Code Playgroud)

编辑:

我发现了Jens Gustedt的与此相关的DR#421,它建议将零/默认初始化仅用于s。我怎样才能知道它是否被接受?atomic_flag

c atomic c11 stdatomic atomicinteger

5
推荐指数
1
解决办法
84
查看次数