我在采访中遇到了以下问题:
让我们假设一个简单的类
public class Example{
private int a;
public void update(){
a = some new value;
}
public int getA(){
return a;
}
}
现在有2个线程(T1和T2)按以下顺序读取和更新a
值:
T2 (call update() and the value was set to 1)
T1 (call getA())
T2 (call update() and the value was set to 2)
T1 (call getA())
线程getA()
的最后一次调用T1
是否可以返回值1
?如果是,在什么情况下?
答案 0 :(得分:2)
对T1的最后一次调用可能会返回0,1或2.在什么情况下询问"并不是真的有意义。"在运行此代码的情况下,基本上。该代码不是为了并发而编写的,因此无法保证。
为了保证一个线程对一个变量的写入对另一个线程读取该变量是可见的,所以线程之间需要有一个同步点。否则,允许JVM以这样的方式优化事物:只有创建它们的线程可以看到更改。例如,写入线程的当前值的概念可以高速缓存在处理器上并且稍后或从不写入主存储器。当另一个线程读取该值的主内存时,它会找到初始值(0),陈旧更新(1)或最新更新(2)。
在这种情况下,最简单的解决方法是将a
声明为volatile
变量。你仍然需要一些机制来确保在T1读取之前T2写入,但仅限于弱挂钟时钟。