We require a piece of code to control a thread. For example, use three buttons like start, stop and pause, press one of them and perform the action against it. Li开发者_如何学JAVAke press start then start the thread, press stop actually stops thread and pause perform pause action respectively.
Starting a thread is simple with Thread.start()
. Stopping a thread can be as simple as setting a flag that is checked asychronously in the run method, but may need to include a call to Thread.interrupt()
. Pausing a thread is more problematic, but could also be done using a flag that cauases the run method to yield instead of process. Here is some (untested) code:
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()
}
}
As you can see it can quite quickly get complex depending on what you are doing in the thread.
I would like to add on Richard's answer to address a few issues:
- Needless cycles when paused
- Needless extra cycle when state changed
yield()
used wherewait()
needed- Single instance
- Stopping the thread waits for the thread to finish
This is my altered code:
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();
}
}
}
精彩评论