Можем ли мы использовать метод wait () для конструкторов?Джава - PullRequest
2 голосов
/ 13 января 2011

Можем ли мы использовать метод wait () для конструкторов? У меня есть метод конструктора, в котором я вызываю некоторые другие методы инициализаторов и после методов для GUI. Но кажется, что он загружает графический интерфейс перед первыми методами. Так что это дает ошибки объектам, которые не были инициализированы. Я пытался использовать wait () перед вызовом gui, но возникла ошибка IllegalMonitorStateException, поскольку он не находится в синхронизированном блоке.

Попытка сделать что-то подобное:

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

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

Ответы [ 3 ]

6 голосов
/ 13 января 2011

Как вы заметили, вы должны звонить 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();
4 голосов
/ 13 января 2011

Ну, вы можете использовать wait внутри конструктора - вам просто нужно синхронизировать "this" внутри конструктора:

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

Однако, неясно, что будет notify ссылкой, если вы не слили "this" в конструкторе к чему-то, что использовало его в другом потоке.

Честно говоря, не совсем понятно, с чего это невозможно, хотя я подозреваю, что это связано с утечкой "this" в конце конструктора. Ваши методы инициализации запускают дополнительные потоки для выполнения своей работы? Мне кажется, что вы должны точно выяснить, что происходит, прежде чем пытаться это исправить - и просто сделать паузу на некоторое время мне кажется плохой идеей.

1 голос
/ 13 января 2011

Можем ли мы использовать метод wait () для конструкторов?

Не совсем, как указывали другие.

Но вы можете разделить код конструктора на две части,Сделайте ту часть, которую можно безопасно выполнить до того, как ваш GUI будет создан в конструкторе.Выполните часть, которая должна ждать создания GUI, в методе initialize (), который можно вызвать после создания GUI.

...