2014-02-28 51 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將其從睡眠中喚醒。

相關問題