Java同步线程

时间:2013-05-08 06:03:19

标签: java multithreading java.util.concurrent

不确定此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;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

  

是否有竞争条件?

如果你在没有正确同步的情况下访问共享变量(f),可能会从多个线程调用i

但请注意,启动一个帖子会创建一个先发生过的关系

所以g将等于线程开始之前i的值(即调用id.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()可以保证irun()可以看到run()不会更改i。否则,您需要AtomicIntegersynchronized。请注意,只有volatile i无效,有些i++可能会丢失。