fla*_*ash 2 java algorithm multithreading 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;
}
Run Code Online (Sandbox Code Playgroud)
更新:
下面是我的方法,我也使用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;
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,我认为你需要compareAndSet这个.
int counter;
int newCounter;
do {
counter = clientCounter.get();
newCounter = counter < Integer.MAX_VALUE ? counter + 1 : 1;
} while (!clientCounter.compareAndSet(counter, newCounter));
return newCounter;
Run Code Online (Sandbox Code Playgroud)