2014-02-28 105 views
1

我正在使用Java和Swing绘图应用程序。它有一个持续运行的不断更新循环,只要布尔变量设置为true即可。循环位于线程内部。如何重新启动应用程序的更新循环

它工作正常,但现在我希望循环只能在特定时间运行(仅当按下鼠标时),否则不会运行。 (因此不会浪费任何东西的记忆)。

要停止循环,我可以简单地将该变量设置为false。但我的问题是,如何在停止后重新启动循环?将该变量设置回true将不会重新启动循环。什么是这样做的好方法?

编辑:我的(一点点简化)循环:

public void run(){ 

    int TICKS_PER_SECOND = 50; 
    int SKIP_TICKS = 1000/TICKS_PER_SECOND; 
    int MAX_FRAMESKIP = 10; 

    long next_game_tick = System.currentTimeMillis(); 
    int loops; 

    boolean app_is_running = true; 

    while(app_is_running) { 

     loops = 0; 
     while(System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) { 

      update(); 

      next_game_tick += SKIP_TICKS; 
      loops++; 
     } 

     repaint(); 
    } 

} 
+0

@peeskillet当然,请参阅我的编辑 –

+0

@peeskillet是的,但据我所知,有时候停止线程是一个问题,这相对困难(当然开始很容易)。但理论上,你建议在停止循环时停止线程并在想要重新启动循环时启动它? –

+0

请检查http://docs.oracle.com/javase/7/docs/api/java/awt/SecondaryLoop.html –

回答

0

要,同时由一个外部定义的布尔可控执行线程体每FRAME_RATE毫秒一次,run方法可以构造为这样:

public void run() 
{ 
    long delay; 
    long frameStart = System.currentTimeMillis(); 

    // INSERT YOUR INITIALIZATION CODE HERE 

    try 
    { 
     while (true) 
     { 
      if (active) // Boolean defined outside of thread 
      { 
       // INSERT YOUR LOOP CODE HERE 
      } 

      frameStart += FRAME_RATE; 
      delay = frameStart - System.currentTimeMillis(); 
      if (delay > 0) 
      { 
       Thread.sleep(delay); 
      } 
     } 
    } 
    catch (InterruptedException exception) {} 
} 

此外,如果您想消除持续运行循环的轻微开销(对于主要为的非活动线程),while循环中的布尔值coul d用Semaphore对象替换:

while (true) 
{ 
    semaphore.acquire(); // Semaphore defined outside thread with 1 permit 

    // INSERT YOUR LOOP CODE HERE 

    semaphore.release(); 

    frameStart += FRAME_RATE; 
    delay = frameStart - System.currentTimeMillis(); 
    if (delay > 0) 
    { 
     Thread.sleep(delay); 
    } 
} 

要停止循环外部使用semaphore.acquire();重新启动它使用semaphore.release()

0

使用Object.wait在线程未运行时挂起线程。让另一个线程调用Object.notify将其从睡眠中唤醒。

相关问题