只是为了确保我理解java实践中呈现的概念。java中的初始化安全性
可以说我有以下程序:
public class Stuff{
private int x;
public Stuff(int x){
this.x=x;
}
public int getX(){return x;}
}
public class UseStuff(){
private Stuff s;
public void makeStuff(int x){
s=new Stuff(x);
}
public int useStuff(){
return s.getX();
}
}
如果我让多个线程使用此代码打球,那么我不仅麻烦,因为S可能会发生被指向如果两个或更多的多个实例线程正在进入makeStuff方法,但即使只有一个线程创建了一个新的Stuff,那么刚刚进入useStuff的其他线程可以通过其构造函数返回值0(预定义的int值)或分配给“x”的值。
这一切都取决于构造函数是否已完成初始化x。
所以在这一点上,为了使线程安全,我必须做一件事,然后我可以从两种不同的方式中选择。
首先,我必须make makeStuff()原子,所以“s”将一次指向一个对象。
然后,我要么使useStuff同步,以确保我只能在其构造函数完成构建后才能返回Stuff对象x var,或者我可以使Stuff的x最终,并由此JMM确保x的值只有在初始化后才可见。
我了解最终字段在并发和JMM上下文中的重要性吗?
假设UseStuff的实例在线程之间共享,那么:no,s将始终指向一次只有一个实例。你的问题是你不确定它是哪个实例,因为多个线程可能会覆盖该引用。通过将其设置为final,您可以确保在UseStuff初始化时设置了引用s,并且在任何线程中都不会更改它。 – Gergely 2015-02-23 21:23:04
对不起,只是注意到你想做x最后。所以在这种情况下,你要保证一旦创建了一个Stuff实例,它的字段x就再也不会被改变了。在这种情况下,字段仍然可以被新的Stuff覆盖,但是至少可以确定Stuff的特定实例永远不会有任何线程更改其x。 – Gergely 2015-02-23 21:29:23