2010-07-05 47 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(); 
     } 
    } 
}