我正在学习java.util.concurrent.atomic包,并尝试使用Atomic Integer。根据我的理解,原子包有助于编写无锁代码,而不是使用同步块。因此,为了测试我的理解,我编写了以下代码:
public class Test{
private final AtomicInteger ai;
public void increment() {
int oldVal = ai.get();
while(!ai.compareAndSet(oldVal, oldVal+1)) {
oldVal = ai.get();
}
}
public int incrementModified() {
return ai.incrementAndGet();
}
public int get() {
return ai.get();
}
public static void main(String[] args) {
Test pc = new Test(5);
Runnable r1 = () -> {
pc.increment();
};
Runnable r2 = () -> {
pc.increment();
};
Runnable r3 = () -> {
pc.increment();
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Thread t3 = new Thread(r3);
t1.start();
t2.start();
t3.start();
System.out.println(pc.get());
}当我执行上面的代码时,我希望输出是8,但是我得到的输出是7/8。然后,我甚至使用内置的incrementAndGet()方法,在运行程序多次之后仍然得到相同的输出。
根据我的理解,因为原子可以作为同步块的替代物,并且通过使用CAS(比较和设置指令)使增量操作成为原子化,所以应该始终将输出作为8。
但是由于我得到了不同的输出,我假设存在一个竞赛,因此o/p在7/8之间变化。
有人能指出我在上面的代码中所犯的错误,或者纠正我对Java中原子类的理解吗?
编辑:
正如注释中指出的那样,我没有使用join(),因此得到了不正确的结果,因为主线程正在请求值,而一些线程可能还在操作的中间。我添加了它,经过多次测试,我可以看到预期的结果。
发布于 2019-06-15 21:31:37
打印值的行将并发执行到其他3个线程。如果您想确保它在3个线程运行后执行,那么您需要在这些线程上加入()。
https://stackoverflow.com/questions/56614249
复制相似问题