应用 java AtomicIntegeraccumulateAndGet

标签 java concurrency atomicinteger

我有一个 Counter 类,它将值存储为 AtomicInteger。该类应该是线程安全的。我有方法boolean consume(int number)应该减少计数器并返回 true如果counter >= number ,并且不应更改计数器并返回 false如果counter < number

class Counter {
   AtomicInteger counter = new AtomicInteger(initialValue);

   boolean consume(int number) {
     counter.accumulateAndGet(number, (prev, next) -> {
            if (number <= prev) {
                return prev - number;
            } else {
                // not modify the previous number;
                return prev;
            }
        });
       return ???
   }
}

而且我不知道该功能是否适用。我找到了以下解决方案

boolean consume(int number) {
    AtomicBoolean result = new AtomicBoolean(false);
    counter.accumulateAndGet(number, (prev, next) -> {
            if (number <= prev) {
                result.set(true);
                return prev - number;
                // function applied
            } else {
                result.set(false);
                // not modify the previous number;
                return prev;
            }
    });
    return result.get();
}

但是 accumulateAndGet 的 javadoc赛伊:

The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads.

所以,我的解决方案有副作用。使用安全吗?如果不是,我怎样才能得到相同的结果?

最佳答案

从描述来看,听起来好像您想要类似的东西:

class Counter {
    private final int initialValue = 42; // make compile

    /** Non-negative count. */
    private final AtomicInteger counter = new AtomicInteger(initialValue);

    public boolean consume(int number) {
        for (;;) {
           int old = counter.get();
           int next = old-number;

           if (next >= 0) {
               if (counter.compareAndSet(old, next)) {
                   return true;
               };
           } else {
               return false;
           }
        }
    }
}

since it may be re-applied when attempted updates fail due to contention among threads.

问题中的代码可以执行一次或多次,但如果方便方法不方便,则使用这些方法无济于事。

关于应用 java AtomicIntegeraccumulateAndGet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59126244/

相关文章:

elasticsearch - Elasticsearch多重搜寻API

java - Java中的生产者/消费者模式

java - 我应该如何使用 AtomicInteger 作为引用计数器来管理某些资源?

javascript - 如何隐藏地址栏中的Url?

java - 寻找一个测试来重现损坏的双重检查锁定

c# - 调用 API 20 次来生成列表,最佳实践?

java - 一些 AtomicInteger 方法的实际例子

java - Spring 配置 : Unable to locate Spring NamespaceHandler

java - NDEF_DISCOVERED 的多个 Activity