对象构造是原子的还是不是?

时间:2012-05-10 08:40:16

标签: java multithreading concurrency

java ThreadSafe中的对象构造吗?请参考下面的代码片段。

//We have some peace of code
public ABCClass(SomeOtherClass obj) {

    obj.setState(XYZ);

}

然后在某处50个线程同时构造ABCClass对象。在构造时我们正在改变SomeOtherClass对象的状态。

我的问题是这个构造过程是原子的,或者线程会看到SomeOtherClass对象的陈旧状态,因为它们在所有ABCClass的实例之间共享。

编辑: obj对象正在所有构造函数中共享。

class SomeOtherClass{

private Status state;

public void setState(Status st){

    this.state=st;
}   

} 
//  Test Class
class TestClass{

public static void main(String[] args) {

    final SomeOtherClass smc=new SomeOtherClass();

    for(int i=0;i<50;i++)
    {
        new Thread(new Runnable() {

            @Override
            public void run() {
                new ABCClass(smc);

            }
        }).start();
    }
}

}

5 个答案:

答案 0 :(得分:2)

你的问题与构造函数无关,但是在线程之间共享SomeOtherClass obj并同时改变它 - 这是一个并发问题。您必须确保此对象的所有突变都是线程安全的。

更新

代码证明了以下评论的重点:

public class Test {
  static Test t1;
  public Test() {
    System.out.println("Constructing Test");
    t1 = this;
    try { Thread.sleep(2000); } catch (Exception e) {}
    System.out.println("Almost done");
  }
  public static void main(String[] args) throws InterruptedException {
    new Thread() { public void run() { new Test(); }}.start();
    Thread.sleep(1000);
    System.out.println(t1);
  }
}

答案 1 :(得分:1)

我不认为构造过程是原子的,内存分配和初始化是复合动作。另外,如果传入相同的对象OBJ用于构造对象,比如50个线程,那么方法obj.setState(XYZ)应该是线程安全的...这就是你想要确定的所有内容。

答案 2 :(得分:0)

将在每个线程的上下文中创建对象,它将是原子的,没有线程可以看到其他线程的状态,所以没有副作用但是如果在线程之间共享object / instanceVariable(静态)那么那里,您可能需要提供并发控制

答案 3 :(得分:0)

如果每个线程都在创建新对象并修改其状态,那么并发不是问题,因为每个线程都有自己的对象可以处理。

如果一个对象被多个线程修改,则会出现问题。在这种情况下,您需要提供访问共享对象的同步方式。

详细了解here

答案 4 :(得分:0)

如果SomeOtherClass的对象在ABCClass中并且它是静态的,则可以在此静态对象上进行同步。

如果你的SomeOtherClass的对象在ABCClass中并且它不是静态的,那么你不关心同步,因为每个对象只实例化一次 - 这意味着构造只调用一次ABCClass的对象。