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();
}
}
}
答案 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的对象。