我们可以在构造函数上使用wait()方法吗? Java的

时间:2011-01-13 17:02:06

标签: java concurrency constructor wait

我们可以在构造函数上使用wait()方法吗? 我有一个构造函数方法,其中我调用一些其他初始化方法和gui方法之后。但它接缝是它在第一种方法之前加载gui。因此它会给尚未初始化的对象带来错误。我试着在gui的调用之前使用wait()但是有一个IllegalMonitorStateException错误,因为它不在同步块中。

尝试这样做:

dice = new Dice();
this.generateBoard();
this.generateCells();

this.wait(200,100);   //otherwise??
//GUI
board = new GUI(this);

3 个答案:

答案 0 :(得分:6)

如您所述,您应该在wait()块内致电synchronized。默认情况下,同步意味着您锁定this,因此实际上在完全构建对象之前发布该对象 - 非常糟糕的想法。

但是 - 正如@Jon指出的那样 - 即使您明确锁定了与this不同的对象,您仍然需要过早地将this发布到另一个线程以便wait()有意义(否则谁能notify()?)。所以这个计划闻起来。

更好的选择是使用静态工厂方法完全构造对象,然后安全地发布它:

class MyClass {
  private MyClass() {
    ...
  }
  public static MyClass createAndPublish() {
    MyClass theInstance = new MyClass();
    // here you can already synchronize on theInstance, call wait() etc.
    return theInstance;
  }
}

请注意,构造函数已声明为private,以确保创建新实例的唯一方法是通过createAndPublish()

MyClass newInstance = MyClass.createAndPublish();

答案 1 :(得分:4)

嗯,你可以在构造函数中使用wait - 你只需要在构造函数中同步“this”:

// I'm not actually recommending this...
synchronized (this) {
    this.wait(...);
}

但是,不清楚引用的notify是什么,除非你在构造函数中将“this”泄露给在另一个线程中使用它的东西。

一点也不清楚这是不是开始时诚实 - 虽然我怀疑这与在构造函数的末尾泄漏“this”有关。您的初始化方法是否启动额外的线程来完成它们的工作在我看来,你应该在尝试修复它之前找到完全正在发生的事情 - 并且暂停一段时间对我来说似乎是一个坏主意。

答案 2 :(得分:1)

  

我们可以在构造函数上使用wait()方法吗?

并非如其他人所指出的那样。

但是你可以将构造函数代码分成两部分。在构造函数中创建GUI之前,可以安全地完成该部分。是否必须等待在initialize()方法中创建GUI的部分,可以在GUI创建之后调用。