如果它将以线程安全的方式溢出,则将AtomicInteger重置为零

时间:2019-01-17 18:55:26

标签: java multithreading algorithm thread-safety

我有一个AtomicInteger,该线程正在由多个线程递增。

如果AtomicInteger溢出但以原子方式,我想重置为零。我想确保counter变量值始终为正,以便一旦clientCounter溢出或即将溢出,我将把AtomicInteger重置为零。我想出了以下代码,但是我不确定它是否线程安全,因为我正在做其他检查和重置操作。有更好的方法吗?

  private static final AtomicInteger clientCounter = new AtomicInteger(0);

  // called by multiple threads
  public static int getCounter() {
    final int counter = clientCounter.incrementAndGet();

    // reset "clientCounter" to zero as soon as it overflow
    // basically I don't want "counter" value should be negative if it overflow
    // is below thread safe?
    if (counter + 1 < 0) {
      clientCounter.set(0);
    }

    if (counter % SIZE == 0) {
        // save counter in database
    }

    return counter;
  }

更新

下面是我的方法,我也使用newCounter值保存在数据库中。我在数据库中保存的行要求将newCounter设置为最终变量,而在这里我不能将newCounter设置为最终变量。现在如何解决这个问题?

  public static int getCounter() {
    int counter;
    int newCounter;
    do {
        counter = clientCounter.get();
        newCounter = counter < Integer.MAX_VALUE ? counter + 1 : 1;
    } while (!clientCounter.compareAndSet(counter, newCounter));

    if (newCounter % SIZE == 0) {
      Executors.newSingleThreadExecutor().execute(new Runnable() {
        @Override
        public void run() {
          // this is asking "newCounter" to make final
          DBClient.getInstance().save(newCounter);
        }
      });
    }

    return newCounter;
  }

1 个答案:

答案 0 :(得分:6)

如果我正确理解,我认为您需要compareAndSet

int counter;
int newCounter;
do {
    counter = clientCounter.get();
    newCounter = counter < Integer.MAX_VALUE ? counter + 1 : 1;
} while (!clientCounter.compareAndSet(counter, newCounter));
return newCounter;