开发者

Control thread through button

开发者 https://www.devze.com 2023-01-05 13:53 出处:网络
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 s

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:

  1. Needless cycles when paused
  2. Needless extra cycle when state changed
  3. yield() used where wait() needed
  4. Single instance
  5. 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();
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消