不确定此D类线程是否正确。是否有竞争条件,访问时i
是否应该在同步块中?如果D是外部类,并且A实例被传递给D构造函数,该怎么办?
class A
{
int i;
void f() {
i++;
D d = new D();
d.start();
}
class D extends Thread {
public void run() {
int g = i;
}
}
}
答案 0 :(得分:1)
是否有竞争条件?
如果你在没有正确同步的情况下访问共享变量(f
),可能会从多个线程调用i
。
但请注意,启动一个帖子会创建一个先发生过的关系。
所以g
将等于线程开始之前i
的值(即调用i
时d.start()
的值)或任何后续值如果i
在此期间被另一个线程修改过(不保证实际看到这样的修改)。
答案 1 :(得分:1)
只要您只调用一次f
,这就是安全的。在变异数据的线程A和从线程A开始的线程B(HB关系在Thread.start
)之间存在一个先发生的关系。由于在D
启动后没有人改变数据,这是安全的。
打破线程安全的一些方法:
i
,包括再次调用foo
i
以外的线程或调用D
foo
即使从调用i
的线程中再次变异foo
的原因是d.start()
之后发生了这种变异,因此没有HB反对第二个突变。
您无法从任意线程中读取i
的原因是该线程没有明确定义的i++
突变视图。
它可能会比这更微妙,但在高层次,你去。
答案 2 :(得分:1)
如果f()
将从同一个线程调用,则不会有任何问题,因为start()
可以保证i
和run()
可以看到run()
不会更改i
。否则,您需要AtomicInteger
或synchronized
。请注意,只有volatile i
无效,有些i++
可能会丢失。