且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何强制停止线程并使用新变量启动同一线程?

更新时间:2021-09-09 23:21:57

我正在发布一个基于Java的纯代码,该代码也将在android中工作.使用android时,请注意不要从不是在主GUI线程之外的线程中执行的程序的一部分更新GUI.如果希望从另一个线程编辑GUI,则可以使用在主GUI线程中实例化的Handler.

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

现在具体实施

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

要暂停线程时,只需调用requestPause()方法

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

resumable.requestPause();

现在,当您需要使用新的变量值恢复线程时,可以调用resumeWithNewParam.

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

resumable.resumeWithNewParam(20);

现在,当您觉得不需要线程并且模型应该终止时,您可以调用resumable.requestStop();

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