2013-06-08 3 views
3

Я просто писал код, и мне это пришло в голову. Я создаю объект Timer и планирую повторение задачи через timer.scheduleAtFixedRate(...).Java Object init() и класс Timer

public class MyClass { 
    .. 
    public MyClass() { 
    Timer timer = new Timer(true); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      doStuffEachSecond(); 
     } 
    }, (long)0, (long)1000); 
    // more stuff 
    } 

Теперь doStuffEachSecond() является метод экземпляра на MyClass. Поскольку моя начальная задержка составляет ноль, , и после создания моего таймера происходит больше вещей, которые появляются в конструкторе, как я узнаю, что первый вызов моего таймера не произойдет до Инициализация объекта завершена ? Или, возможно, это может быть так (что, конечно, не будет хорошо)?

На данный момент мое решение заключается в том, что установка моего таймера - это конечный шаг конструктора, но это в лучшем случае выглядит, если это возможно. Любая мудрость в отношении этой проблемы?

+2

Offtopic: Вы можете просто использовать '' 0L' и 1000L' вместо литья с '(длинный)' – Doorknob

+0

Может быть, вы можете попробовать добавить 'trifle' оттянуть – kyriosli

ответ

1

Я бы использовал что-то похожее на то, что делают потоки в Java. Возьмите конструктор, затем вызовите метод start, чтобы начать таймер.

Устранение проблем с расы здесь кажется немного переборщившим, когда вы можете просто построить объект, а затем сразу начать отсчет времени. Если у вас есть Factory для создания объектов, это может быть частью процесса построения.

+0

Я думаю, что вы и Grezegorz должны предложить сидит лучше со мной. Я предпочел бы быть на 100% безопасным, отпустив таймер после завершения инициализации объекта, а не запускать его во время строительства, что «вероятно» будет в порядке. – fragorl

2

Если вы действительно хотите, чтобы убедиться, что MyClass полностью инициализирован перед таймер запускается, вы можете сделать инициализацию и запуск таймера в два этапа:

final MyClass myMlass = new MyClass(); 
Timer timer = new Timer(true); 
timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
     myclass.doStuffEachSecond(); 
    } 
}, 0L, 1000L); 

Редактировать

Подумав об этом, положив вышеперечисленное в статическом заводском методе, будет far лучшим soluti на:

public class MyClass { 
    private MyClass() { /* do stuff */ } 
    public static MyClass createNew() { 
    MyClass myClass = new MyClass(); 
    myClass.startRunning(); 
    } 
    private void startRunning() { 
    new Timer(true).scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      doStuffEachSecond(); 
     } 
    }, 0L, 1000L); 
    } 
} 

Это делает все вы хотите. Единственный способ создать новый MyClass - это его фабричный метод, и всякий раз, когда создается новый, его таймер запускается после, он инициализируется.

0
Do this instead: Call the method in the class you are using the MyClass object. 


    public class MyClass { 
    public MyClass() { 
      // more stuff 
      } 
     private void startTimer(){ 
      Timer timer = new Timer(true); 
      timer.scheduleAtFixedRate(new TimerTask() { 
       @Override 
       public void run() { 
        doStuffEachSecond(); 
       } 
      }, (long)0, (long)1000); 
     } 

    public class usingClass{ 
      public static void main(String args[]){ 
       MyClass mc=new MyClass(); 
       mc.startTimer(); 
      } 

    } 
1

Я бы отдельное планирование от создания объекта. Вы правы, что пахнет.

public class MyClass { 

    ... 

    public MyClass() { 
    ... 
    } 

    public static void start(final MyClass mc) { 
    Timer timer = new Timer(true); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      mc.doStuffEachSecond(); 
     } 
    }, (long)0, (long)1000); 
    } 

}