将periodic Task与另一个Thread同步

时间:2013-08-29 15:58:57

标签: java multithreading concurrency

我在游戏中遇到以下情况:

class GameLogic implements Runnable
{
    State state;

    private State changeState()
    {
        //state changes here (note the `private`)
    }

    // this ticks at each 0.5 seconds
    public void run()
    {
      //code that changes state
      changeState();
    }

    // this will be called by a external Thread at any moment
    public void update(Move move)
    {
       //code that changes state
       applyMove(move);
    }

    private void applyMove(Move move)
    {
         //state changes here
         //state = ... doesn't matter
    }

}

上面的run方法计划在每0.5秒执行一次,使用 Timer ScheduledExecutorService

问题是update方法,任何时候都会被另一个线程调用。所以我问:

1 - 如果使用synchronized来保护state字段会怎样?计时器会等待吗?它将如何弥补“等待期”?

2 - 有更好的方法吗?也许将moves存储在某个队列中?

谢谢!

2 个答案:

答案 0 :(得分:1)

  1. TimerScheduledExecutorService都可以执行固定费率固定延迟执行任务。这意味着,具有固定费率的计划任务将补偿执行的运行时间(包括阻塞时间)。具有固定延迟的计划任务不会。有关更多信息,请参阅以下方法的文档:
  2. 总会有更好的方法。但是,解决方案看起来很好。只要它对你有用,就去吧。

答案 1 :(得分:0)

处理此问题的另一种方法是让更新线程中的更新转到Queue或类似的东西。这样,在调整状态的每次迭代中,您都可以从队列中获取所有更新并将它们应用于同一个线程中。

使用此方法,更新线程和游戏循环线程之间永远不会有任何冲突。

就个人而言,我会使用while循环,它利用一些调节机制而不是调度任何东西。您可以使用System.nanoTime()以使用时间增量来应用更新。这将确保逻辑的执行不受机器性能的约束。

有关于here主题的精彩文章。