相关疑难解决方法(0)

Java中的构造函数同步

有人告诉我,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

假设put/get是地图上唯一的操作,所以我不会通过迭代之类的东西获得CME,并试图忽略其他明显的缺陷.

我想知道的是,如果另一个线程(显然不是那个构造对象的线程)尝试使用getTestById并调用它上面的东西来访问该对象,它会阻塞吗?换一种说法:

Test test = getTestById(someId);
test.doSomething(); // Does this line block until the constructor is done?
Run Code Online (Sandbox Code Playgroud)

我只是想弄清楚构造函数同步在Java中走了多远,以及像这样的代码是否有问题.我最近看过像这样的代码,而不是使用静态工厂方法,我想知道这在多线程系统中是多么危险(或安全).

java concurrency multithreading constructor

19
推荐指数
3
解决办法
1万
查看次数

同步对象并更改引用

假设我有一个对象如下:

Map<String, String> m = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

然后我按如下方式同步该对象并更改其引用:

synchronize(m){
    m = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)

有了这段代码,m 上的锁会发生什么情况?更新 m 代表的新对象是否仍然安全?或者锁本质上是在旧对象上?

java concurrency multithreading synchronized synchronized-block

6
推荐指数
1
解决办法
3830
查看次数