Control thread through button

旧城冷巷雨未停 提交于 2019-12-25 02:49:23

问题


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. Like press start then start the thread, press stop actually stops thread and pause perform pause action respectively.


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/3178129/start-and-stop-thread-control-through-button

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!