java中使用方法限制的多线程安全发布
考虑类中的一个片段:
// tail call to show
void showNextPoint(){
Point p = new Point();
p.x = 10;
p.y = 12;
show(p);
}
// multiple calls to show
void showPoints(){
Point p = new Point();
p.x = 10; p.y = 12;
show(p);
p.x = 20; p.y = 22;
show(p);
p.x = 30; p.y = 32;
show(p);
}
void show(Point p){
// use p in some way
// can p's state be changed safely ?
// can a new thread be started to work with p safely ?
}
在多线程用例中,对象p
可以被认为是从showPoints()
或showNextPoint()
安全发布的吗?在show()
中什么条件必须成立
如果保证show(Point p)
1)不启动新线程,2)不更改p的状态,那么showPoints()
方法是否可以被视为安全发布p
# 1 楼答案
show()
方法获取对Point p
的引用。如果调用方随后对p
进行更改,则它正在对相同的对象进行更改。如果show()
以任何方式更改了p
,则它正在更新调用者正在使用的相同p
对象。如果一个线程是分叉的,它有这个p
,那么您就有一个竞态条件,即按照哪个顺序执行对p
的更新你问:
不能在不影响调用者对象的情况下安全地更改它。当内存同步发生时,新线程也不能在不影响调用者对象的情况下更改
p
这完全取决于您如何编写代码以及合同是什么。如果一个方法对一个对象进行了更改,那么它应该被记录下来。如果调用方不希望这样做,那么您应该传入该方法可以“拥有”的
Point
对象的副本,或者该方法本身应该复制Point
本身同步对象更改的复杂性是许多Java对象不可变的原因之一。你可以考虑这样做{{CD10}}。使
x
和y
值不能更改,这意味着show
方法及其生成的任何线程都可以安全地使用参数,而不必担心调用方对其进行更改编辑:
@JohnVint对此有一些更好的观点,但我想我会补充我的想法。我不知道你在问什么,也不知道你认为“安全出版”意味着什么。魔鬼在于细节。如果
show()
没有启动新线程,那么是的,您发布的代码将起作用,可以使用相同的可变Point
对象任何接受对象参数但不以任何方式更改对象的方法都可以说它正在“安全地使用”(我猜)对象。因为
showPoints()
构造了对象,并且只有对它的引用,所以这当然也是安全的。只有当p
被修改,并且涉及到另一个线程时,一切都会发生变化