【问题标题】:Can we call synchronized method of an object inside the constructor of the object in Java?我们可以在Java中对象的构造函数中调用对象的同步方法吗?
【发布时间】:2019-06-12 18:28:17
【问题描述】:

我是 Java 新手。我想知道是否可以在构造函数中调用同步方法。有例子:

class a{
    int a1;

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

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

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

【问题讨论】:

  • 提示:即使在示例代码中,也要使用合理的名称。类名采用大写字母,a 和 a1 ... 看起来几乎相同,但您将它们用于完全不同的事物。不要那样做。使用能表达其含义的名称!

标签: java class constructor synchronized


【解决方案1】:

你可以这样做,但是同步是没有意义的,因为同步方法会锁定当前正在创建的实例。但是在尚未创建和返回的情况下,哪个其他线程可以访问它?没有人。
只要您遵循良好做法,例如不将this 传递给构造函数主体内的其他类/对象,构造函数实际上是线程安全的。
使用synchronized static 方法或static 字段上的synchronized,您的示例可能更有意义。

【讨论】:

  • 将 'increment' 更改为 public 会使示例更合理。然后,构造函数之外的调用者具有同步的优势,而来自构造函数的调用可以重用“增量”中的代码(并且在大多数情况下,忽略同步。)同步并不是完全 毫无意义,因为构造函数可能会将未完全初始化的对象泄漏给其他线程,在这种情况下,可能会在新对象仍在初始化时调用同步方法。 (这是一个罕见但并非不存在的问题。)
  • “构造函数实际上是线程安全的。” ...这通常是正确的,除非构造函数使用this 调用非最终实例方法作为论据。在这种情况下,API 的客户端可以观察仅处于部分构造状态的对象并将对该对象的引用发布到其他线程。
  • @scottb 同意。在构造函数中传递 this 确实是要避免的,但这仍然是可能的。我将这一点添加为简单而相关的。
猜你喜欢
  • 2022-11-29
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2013-02-25
  • 2015-05-22
  • 1970-01-01
相关资源
最近更新 更多