这样使用计时器的意图是什么?

时间:2013-07-12 08:20:47

标签: java refactoring

我不明白为什么在以下代码中使用这样的定时器变量。

问题1:在startTimer()和stopTimer()中,有一个局部变量aTimer在定时器操作之前使用,是什么意思?

问题2:在stopTimer()中,timer将被赋值为null,因此如果timer不为null,这意味着已经创建了此计时器,当调用startTimer()时,将不再创建计时器。这是检查计时器是否正在运行的最佳做法吗?通过为计时器分配null,PMD还报告违反“NullAssignment”

private Timer timer;

private void startTimer() {
  if (timer == null) {
    Timer aTimer = timerFactory.createTimer(100000, null);
    aTimer.setListener(this);
    timer = aTimer;
  }
}

private void stopTimer() {
  if (timer != null) {
    Timer aTimer = timer;
    timer = null;
    aTimer.cancel();
    aTimer.setListener(null);
 }
}

public void start() {
  synchronized(..) {
     startTimer();
  }
}

public void stop() {
 synchronized(..) {
     stopTimer();
 }
}

3 个答案:

答案 0 :(得分:1)

您的代码相当于:

private boolean started = false;
private Timer timer;

public synchronized void start() {
    if (!started) {
        timer = timerFactory.createTimer(100000, null);
        timer.setListener(this);
        started = true;
    }
}

public synchronized void stop() {
    if (started) {
        timer.cancel();
        timer.setListener(null);
        started = false;
    }
}

更短更容易理解(恕我直言)。局部变量是多余的,因为您的代码已同步,并且两个线程无法同时访问您的timer变量。

使用timernull作为启动/未启动标志的事实可以很好地使用如此短的代码,但随着更多行的添加,它将变得令人困惑。我更喜欢一个不言自明的started标志。

答案 1 :(得分:0)

我的假设是这个对象的原作者想要封装Timer对象,这样你就不会错误地在start()和stop()之间重新创建它。

这没有直接的附加价值,但是如果在一个经常使用的对象上与一大群人一起工作,那就是为了防止不必要的访问,弄乱信息或其他东西。

答案 2 :(得分:0)

定时器已同步,以防止线程干扰和内存一致性错误。同步计时器意味着:

  • 其他线程没有线程干扰
  • 确保内存一致性
  • 确保对定时器的原子访问,其中定时器的外部线程无法访问定时器的中间状态。即完成动作或完全没有动作。