我有一个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;
}
答案 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;