【问题标题】:Can two instances be created at the same time?可以同时创建两个实例吗?
【发布时间】:2015-07-02 00:01:31
【问题描述】:

Why can't Java constructors be synchronized? 的一个后续问题:如果一个对象的构造函数不能同步,这是否意味着不可能同时创建两个实例?例如:

public class OutgoingMessage {
    public OutgoingMessage() {
        this.creationTime = new Date();
    }
    Date creationTime;
}

creationDate.getTime() 是否总是返回不同的值?我知道多任务/多线程的基础知识,但是多个 CPU 内核呢?在那种情况下,操作系统不必切换上下文还是我错了?

【问题讨论】:

  • 你的意思是creationTime.getDate()
  • 即使忽略多核 creationTime 对于两个对象仍然可能相同。
  • 对象在构造之前对其他线程不可见并不意味着不能同时构造2个对象
  • @MiroKropacek 在实用程序类中使用同步静态方法。我不相信你真的想要这样做,但不知道你在使用什么价值很难说。
  • 我在这里闻到了 XY 问题;也就是说,您在问问题 X,但 X 不一定是解决您的实际问题 Y 的最佳途径。为什么您关心是否可以“同时”创建两个对象?是不是您不希望两个对象具有相同的creationTime?在这种情况下,编写一个静态方法 getCreationTimeForNewMessage() 保证永远不会多次返回相同的时间戳,并从您的构造函数中调用该方法。或者,如果不是,那么真正的问题是什么?

标签: java multithreading


【解决方案1】:

如果一个对象的构造函数不能同步,那是否意味着不可能同时创建两个实例?

没有。作为另一个问题状态的答案,构造函数不能简单地同步,因为在调用构造函数之前没有任何东西可以同步。你可以这样做:

public OutgoingMessage(){
   synchronized(this){
      //synchronized constructor
   }
}

但是问题就变成了:两个线程到底如何同时访问同一个实例的同一个构造函数?根据构造函数如何工作的定义,他们不能。这就是你不能在构造函数上同步的原因——因为它没有任何意义。

不是说不能同时构造一个类的两个实例。

【讨论】:

  • 哦,哦,这就是我害怕的。私有静态锁对象可以用于此目的吗?
  • @MiroKropacek 这确实取决于您要执行的操作,但是可以肯定的是,您可以在静态锁定对象上进行同步以将构造函数的某些部分限制为单个线程。你也可以参考 BretC 的类本身同步的例子。
【解决方案2】:

如果您想确保构造函数中的代码块永远不会被多个线程同时执行,您可以在 Class 上进行同步,例如...

public class MyClass {
    public MyClass() {
        synchronized(MyClass.class) {
            // Thread unsafe code here!
        }
    }
}

如果您不想使用“MyClass.class”,则不必使用,例如,您可以使用“LOCK”对象...

public class MyClass {
    private static final Object LOCK = new Object();

    public MyClass() {
        synchronized(LOCK) {
            // Thread unsafe code here!
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-04-22
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多