通过按钮控制线程

我们需要一段代码来控制一个线程。 例如,使用三个按钮,如开始,停止和暂停,按下其中一个按钮并对其执行操作。 如按启动然后启动线程,按停止实际停止线程并暂停执行暂停操作。

使用Thread.start()启动一个线程很简单。 停止线程可以像设置在run方法中异步检查的标志一样简单,但可能需要包含对Thread.interrupt()的调用。 暂停线程更有问题,但也可以使用一个标记来处理run方法而不是进程。 这是一些(未经测试的)代码:

 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. 暂停时无需循环
  2. 状态改变时无需额外循环
  3. 在需要wait()地方使用yield()
  4. 单个实例
  5. 停止线程等待线程完成

这是我改变的代码:

 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(); } } }