2010-07-05 88 views
4

我們需要一段代碼來控制線程。例如,使用三個按鈕(如開始,停止和暫停),按其中一個按鈕並對其執行操作。像按開始然後開始線程,按停止實際上停止線程和暫停執行暫停動作分別。通過按鈕控制線程

+0

可能重複[啓動和停止通過按鈕控制線(http://stackoverflow.com/questions/3178129/start-and-stop-thread-control-通過按鈕) – 2010-07-05 16:41:19

回答

4

啓動線程很簡單,Thread.start()。停止線程可以像設置在run方法中異步檢查的標誌一樣簡單,但可能需要包含對Thread.interrupt()的調用。暫停一個線程會產生更多問題,但也可以使用一個使運行方法放棄而不是進程的標誌來完成。這裏是一些(未經測試的)代碼:

class MyThread extends Thread { 
    private final static int STATE_RUN = 0, STATE_PAUSE = 2, STATE_STOP = 3; 
    private int _state; 

    MyThread() { 
     _state = STATE_RUN; 
    } 

    public void run() { 
     int stateTemp; 

     synchronized(this) { 
      stateTemp = _state; 
     } 

     while (stateTemp != STATE_STOP) { 
      switch (stateTemp) { 
       case STATE_RUN: 
        // perform processing 
        break; 
       case STATE_PAUSE: 
        yield(); 
        break; 
      } 
      synchronized(this) { 
       stateTemp = _state; 
      } 
     } 
     // cleanup 
    } 

    public synchronized void stop() { 
     _state = STATE_STOP; 
     // may need to call interrupt() if the processing calls blocking methods. 
    } 

    public synchronized void pause() { 
     _state = STATE_PAUSE; 
     // may need to call interrupt() if the processing calls blocking methods. 
     // perhaps set priority very low with setPriority(MIN_PRIORITY); 
    } 

    public synchronized void unpause() { 
     _state = STATE_RUN; 
     // perhaps restore priority with setPriority(somePriority); 
     // may need to re-establish any blocked calls interrupted by pause() 
    } 
} 

正如你所看到的,它可以很快地變得複雜,這取決於你在線程中做什麼。

+1

使用'this.wait()'而不是'yield()'並將'this.notify()'添加到'unpause()'和'stop()'可能會更好一些。 。 – 2010-07-05 22:14:36

2

我想對理查德的答案添加到解決的幾個問題:

  1. 不用週期暫停
  2. 當狀態改變
  3. yield()用在wait()需要
  4. 單實例
  5. 不用額外的週期時
  6. 停止線程等待線程完成

這是我改變代碼:

class MyThread extends Thread { 
    private final static int STATE_RUN = 0, STATE_PAUSE = 2, STATE_STOP = 3; 
    private int _state; 

    private static MyThread thread; 

    public static MyThread getInstance() { 
     if (thread == null || !thread.isAlive()) { 
      thread = new MyThread(); 
     } 
     return thread; 
    } 


    private MyThread() { 
     _state = STATE_RUN; 
    } 

    public static void main(String[] args) { 
     MyThread t = MyThread.getInstance(); 
     try { 
      t.start(); 
      Thread.sleep(500); 
      t.pause(); 
      Thread.sleep(500); 
      t.unpause(); 
      Thread.sleep(500); 
      t.end(); 
     } catch (InterruptedException e) { 
      // ignore; this is just an example 
     } 
    } 

    public void run() { 
     int i = 0; 
     while (_state != STATE_STOP) { 
      if (_state == STATE_PAUSE) { 
       System.out.println(this + " paused"); 
       synchronized (this) { 
        try { 
         this.wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
      } 
      if (_state == STATE_STOP) { 
       break; 
      } 

      // this is where the actual processing happens 
      try { 
       // slow output down for this example 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       // state change handled next cycle 
      } 

      System.out.println(this + " cycle " + i); 
      i++; 
     } 
     System.out.println(this + " finished"); 
     // cleanup 
    } 

    public synchronized void end() { 
     _state = STATE_STOP; 
     try { 
      this.interrupt(); 
      this.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public synchronized void pause() { 
     _state = STATE_PAUSE; 
    } 

    public synchronized void unpause() { 
     _state = STATE_RUN; 
     synchronized (this) { 
      this.notify(); 
     } 
    } 
}