【发布时间】:2016-11-19 06:56:53
【问题描述】:
这是一项学校作业,但我真的需要一些帮助。我一辈子都想不通为什么nextValue() 的两个不同版本的行为不同——一个是线程安全的,另一个不是。至少有人可以给我一些正确方向的指示吗?
我在下面的同一个类中包含了这两个版本,但显然它们并没有同时出现在代码中......
public class NumGenerator {
static final int MIN_VALUE = -256;
static final int MAX_VALUE = 255;
static final int INITIAL_VALUE = MIN_VALUE -1;
private final AtomicInteger counter = new AtomicInteger(INITIAL_VALUE);
private final AtomicInteger resetCounter = new AtomicInteger(0);
private final Object lock = new Object();
// Thread safe
public int nextValue() {
int next = counter.incrementAndGet();
if (next > MAX_VALUE) {
synchronized (lock) {
next = counter.incrementAndGet();
if (next> MAX_VALUE) {
counter.set(MIN_VALUE);
resetCounter.incrementAndGet();
next = MIN_VALUE;
}
}
}
return next;
}
// Non thread safe
public int nextValue() {
int next = counter.incrementAndGet();
if (next > MAX_VALUE) {
synchronized (lock) {
int i = counter.get();
if (i > MAX_VALUE) {
counter.set(INITIAL_VALUE);
resetCounter.incrementAndGet();
}
next = counter.incrementAndGet();
}
}
return next;
}
}
【问题讨论】:
-
这两个代码的逻辑似乎不一样。恕我直言,这两个函数都是线程安全的。然而,如前所述,这两个函数都可能返回与预期不同的输出。
-
你是对的,它们返回不同的输出...但是为什么呢?在我看来,它们在功能上是相同的。我错过了什么?
-
counter.get();和counter.incrementAndGet();是不同的。所以你会得到不同的输出 -
好的,但那是在外部 IF 语句内......你的意思是不同的线程可能会出现在
int next = ...和synchronized...之间并搞砸结果?我想是的,但还有第二个 IF 语句?
标签: java multithreading synchronization thread-safety atomic