在Java中,我们可以在对象的构造函数中调用对象的同步方法吗?

4

我刚接触Java,想知道是否可以在构造函数中调用同步方法。以下是一个例子:

class a{
    int a1;

    public a(){
        a1 = 1;
        increment();
    }

    private synchronized void increment(){
        a1++;
    }
}

这只是一个玩具示例。我只能在构造函数中将a1设置为2。我只是困惑我们是否可以在构造函数内调用increment()


1
提示:即使在示例代码中,也要使用合理的名称。类名使用大写字母,a、a1等几乎看起来相同,但用于完全不同的事情。不要这样做。使用能够表明它们含义的名称! - GhostCat
1个回答

7
你可以这样做,但同步是毫无意义的,因为同步方法会锁定当前正在创建的实例。但在其还未被创建和返回之前,哪个其他线程能够访问它呢?没有一个。
只要遵循良好的实践,如不将this传递给构造函数体内的其他类/对象,构造函数确实是事实上的线程安全。
你的示例可以更有意义地使用synchronized static方法或static字段上的synchronized

1
将“increment”更改为public会使示例更有意义。然后,在构造函数之外的调用者具有同步的优势,而来自构造函数的调用可以重用“increment”中的代码(并且在很大程度上忽略同步)。同步不是完全没有意义,因为构造函数可能会将未完全初始化的对象泄漏到其他线程中,在这种情况下,对同步方法的调用可能会发生,而新对象仍在初始化过程中。(这是一个罕见但并非不存在的问题。) - Thomas Bitonti
1
构造函数确实是事实上线程安全的。通常情况下,除非构造函数调用一个非 final 实例方法并以 this 作为参数。在这种情况下,客户端可能会观察到处于部分构建状态的对象,并将对该对象的引用发布到其他线程。 - scottb
@scottb 同意。在构造函数中传递这个东西确实是要避免的,但这仍然是可能的。我将这一点添加为简单而相关的内容。 - davidxxx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接