Java Object init()和Timer类

时间:2013-06-08 14:32:50

标签: java concurrency constructor

我只是写了一些代码,它发生在我身上。我正在创建一个Timer对象并通过timer.scheduleAtFixedRate(...)安排重复任务。

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上的实例方法。由于我的初始延迟是, 在我的Timer设置完成后,构造函数中还有更多的东西,我怎么知道在对象初始化完成之前,我的计时器的第一次调用不会发生?或者可能是这种情况(当然不是很好)?

现在我的解决方案是我的计时器的设置 是构造函数的最后一步,但这似乎充其量只是。有关这个问题的任何智慧吗?

4 个答案:

答案 0 :(得分:2)

如果你真的想确保MyClass在定时器启动之前完全初始化,你可以分两步完成初始化和定时器启动:

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

修改

在考虑之后,将上述内容放在静态工厂方法中将是最佳解决方案:

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的唯一方法是通过其工厂方法,每当创建一个新方法时,其计时器在初始化之后启动。

答案 1 :(得分:1)

我会使用类似于Java中的线程的东西。有一个构造函数,然后调用像start这样的方法来启动计时器。

当您可以构建对象然后立即开始计时时,解决竞争问题似乎有点矫枉过正。如果你有一个工厂来创建对象,这可能是构建过程的一部分。

答案 2 :(得分: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);
  }

}

答案 3 :(得分: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();
          }

   }