How to forcefully stop thread and start same thread with new variable?

后端 未结 4 2056
太阳男子
太阳男子 2020-12-12 03:58

I want to do some long running task on a button click, if user click again on that button current task forcefully stopped and will do next task ?

4条回答
  •  旧时难觅i
    2020-12-12 04:24

    I am posting a pure Java based code which will work in android as well. While working with android Just you need to take care that you do not update GUI from a part of the program which gets executed in a Thread other than Main GUI thread. If You wish to edit the GUI from another thread then you may use Handler instantiated in the main GUI thread.

    Define the basic interface for such model

    /**
     * 
     * @author nits.kk
     * 
     * This defines the methods for the model.
     *
     */
    public interface IResumable {
      /**
       * starts the model
       */
      public void requestStart();
      /**
       * requests the model to pause
       */
      public void requestPause();
      /**
       * requests the model to resume with new parameter
       * @param newParam
       */
      public void resumeWithNewParam(int newParam);
     /**
       * terminate the model
       */
      public void requestStop();
    }
    

    Now the concrete implementation

    public class ResumableModel implements IResumable {
      private Thread worker;
      private WorkerRunnable work;
    
      public ResumableModel(int initialValue) {
            work = new WorkerRunnable(initialValue);
            worker = new Thread(work);
      }
    
      @Override
      public void requestStart() {
            worker.start();
      }
    
      @Override
      public void requestPause() {
            work.setPauseRequested(true);
      }
    
      @Override
      public void resumeWithNewParam(int newParam) {
            work.setNewParam(newParam);
      }
    
      @Override
      public void requestStop() {
            worker.interrupt();
      }
    
      private static class WorkerRunnable implements Runnable {
            private int param; // we can have the variable of the type depending upon the requirement.
            private final Object lock = new Object();
            private volatile boolean isPauseRequested = false;
    
            public void run() {
                  synchronized (lock) {
                        try {
                              while (!Thread.currentThread().isInterrupted()) {
                                    while (isPauseRequested) {
                                          lock.wait();
                                    }
                                    System.out.println("value of param is" + param);
                              }
                        } catch (InterruptedException e) {
                              e.printStackTrace();
                        }
                  }
            }
    
            public WorkerRunnable(int param) {
                  this.param = param;
            }
    
            private void setPauseRequested(boolean isPauseRequested) {
                  this.isPauseRequested = isPauseRequested;
            }
    
            private void setNewParam(int param) {
                  // double locking to prevent the calling thread from being locked
                  // (if in running state without pause requested then calling thread
                  // will be in indefinite wait state for acquiring the lock.
                  if (isPauseRequested) {
                        synchronized (lock) {
                              if (isPauseRequested) {
                                    this.param = param;
                                    this.isPauseRequested = false;
                                    lock.notifyAll();
                              } else {
                                    // logger will be used in real application
                                    System.out.println("Need to pause first before setting a new param"); 
                              }
                        }
                  } else {
                        // logger will be used in real application
                        System.out.println("Need to pause first before setting a new param"); 
                  }
            }
      }
    }
    

    Now when you wish to start The thread you can do as below

    IResumable resumable = new ResumableModel(10);
    resumable.requestStart();
    

    When you want to pause the thread you can simply invoke the requestPause() method

    resumable.requestPause();
    

    Now when you need to resume the Thread with a new variable value, you can invoke resumeWithNewParam.

    resumable.resumeWithNewParam(20);
    

    Now when you feel you do not need the thread and model should terminate then you can invoke resumable.requestStop();

提交回复
热议问题