有人告诉我Java构造函数是同步的,因此在构造过程中不能同时访问它,我想知道:如果我有一个将对象存储在映射中的构造函数,并且另一个线程在构建之前从该映射中检索它完成后,该线程会阻塞直到构造函数完成吗?
让我用一些代码来演示:
public class Test {
private static final Map<Integer, Test> testsById =
Collections.synchronizedMap(new HashMap<>());
private static final AtomicInteger atomicIdGenerator = new AtomicInteger();
private final int id;
public Test() {
this.id = atomicIdGenerator.getAndIncrement();
testsById.put(this.id, this);
// Some lengthy operation to fully initialize this object
}
public static Test getTestById(int id) {
return testsById.get(id);
}
}
假设 put/get 是地图上唯一的操作,所以我不会通过迭代之类的方法获得 CME,并尝试忽略此处的其他明显缺陷。
我想知道的是,如果另一个线程(显然不是构造对象的线程)尝试使用getTestById
并调用对象来访问对象,它会阻塞吗?换句话说:
Test test = getTestById(someId);
test.doSomething(); // Does this line block until the constructor is done?
我只是想澄清构造函数同步在 Java 中的进展程度,以及这样的代码是否会出现问题。我最近看到这样的代码,而不是使用静态工厂方法,我想知道这在多线程系统中有多危险(或安全)。