0

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();
    }
}

}

4

5 回答 5

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);
  }
}
于 2012-05-10T09:10:48.750 回答
1

我不认为构造过程是原子的,内存分配和初始化是复合动作。此外,如果您传入相同的对象 OBJ 以在 50 个线程中构造对象,那么方法 obj.setState(XYZ) 应该是线程安全的……这就是您要确保的全部。

于 2012-05-10T08:58:10.033 回答
0

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

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

于 2012-05-10T08:55:37.660 回答
0

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

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

在此处阅读有关它的更多信息

于 2012-05-10T08:52:10.633 回答
0

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

于 2012-05-10T08:42:43.757 回答