英文:
Executing a method call with Java atomic variables
问题
假设我有一个像这样的代码块:
if (counter < 100) {
synchronized (counter)
if (counter < 100) {
doSomething();
counter.incrementAndGet();
}
}
}
其中counter
是一个AtomicLong
。我应该如何修改这个代码块,不再使用synchronized
关键字,同时保持其正确性?或者这是不可能的?
英文:
Suppose I have a code block like this
if (counter < 100) {
synchronized (counter)
if (counter < 100) {
doSomething();
counter.incrementAndGet();
}
}
}
where counter is an AtomicLong
. How would I convert this block to not using the synchronized
keyword anymore and still keeps its correctness? Or is it impossible?
答案1
得分: 1
根据doSomething
的情况而定,你还没有展示它。它可能依赖于从同步块内部调用,并且可能无法并行化。
我认为可能会被接受的一个替代方案是:
if (counter.getAndIncrement() < 100) {
doSomething();
}
但是假设doSomething
总是抛出异常。在你的代码中,计数器永远无法递增,因此条件将始终计算为true。在上面的示例中,它将在前100次被调用,即使它们失败,它们也会被视为一次迭代。
所以简而言之,为了确定是否保持了正确性,你需要非常明确地定义它正确的含义。
如果你不知道它的正确性意味着什么,那最好将其保持原样。
英文:
It all depends on doSomething
which you haven't shown. It may rely on being called from within a synchronized block, and may not even be parallelizable.
One substitution which I think is likely to be acceptable is
if (counter.getAndIncrement() < 100) {
doSomething();
}
But suppose doSomething
always throws an exception. In your code the counter can never be incremented, so the condition will always resolve to true. In the above example, it will be called the first 100 times, and even if they fail they will count as an iteration.
So in short, in order for us say if correctness is maintained then you need to define very specifically what it means for it to be correct.
If you don't know what it means for it to be correct then you are better off leaving it as it is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论