这是一项学校作业,但我真的需要一些帮助。我不能为我的生活弄清楚为什么两个不同版本的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;
}
}
答案 0 :(得分:1)
假设值为:MIN_VALUE = -1,MAX_VALUE = 3,counter = 3.
代码1:
synchronized (lock) {
next = counter.incrementAndGet();
if (next> MAX_VALUE) {
counter.set(MIN_VALUE);
resetCounter.incrementAndGet();
next = MIN_VALUE;
}
}
if(next > MAX_VALUE)
变为if(4> 3),这会将next的值更改为-1并返回它。代码2:
synchronized (lock) {
int i = counter.get();
if (i > MAX_VALUE) {
counter.set(INITIAL_VALUE);
resetCounter.incrementAndGet();
}
next = counter.incrementAndGet();
}
i
的值仍然是3. if(i > MAX_VALUE)
变为if(3> 3),其中不是返回3作为输出。 incrementAndGet
和get
不同。
所以具有相同值的代码返回不同的输出。
一个是首先递增值然后检查条件,另一个是先检查值然后再执行一个操作。
即使if(变量> MAX_VALUE)内的代码也会导致不同的输出。
所以这与线程安全无关。
答案 1 :(得分:0)
认为两种方法在逻辑上都是线程安全的。因为在两种方法中都使用了synchronized。和synchronized块用于线程安全。
答案 2 :(得分:0)
两者都是线程安全的。也许你可以粘贴代码如何测试它们。问题可能在那里。