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



我想在按钮单击时执行一些长时间运行的任务,如果用户再次单击该按钮,当前任务将强制停止并将执行下一个任务?

我正在发布一个纯基于Java的代码,它也可以在Android上运行。在使用android Only时,您需要注意不要从程序的一部分更新GUI,该程序在主GUI线程以外的线程中执行。如果您希望从另一个线程编辑 GUI,则可以使用在主 GUI 线程中实例化的处理程序。

定义此类模型的基本接口

/**
 * 
 * @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"); 
              }
        }
  }
}

现在,当您希望启动线程时,您可以执行以下操作

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

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

resumable.requestPause();

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

resumable.resumeWithNewParam(20);

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

您必须不断检查运行方法中的标志。当您希望线程取消时,可以将此标志设置为 false。下次您的 run 方法检查此标志时,因为它为 false,因此它会退出线程。您可能想使用 ThreadPoolExecutor?

线程停止后无法重新启动。

我建议使用 Looper/Handler API 将任务放入队列中,让处理程序在单独的线程上执行它们。

我这里有活套/处理程序的演示项目,并附有解释。如果您想以这种方式实现它,请查看一下。

另一种选择(如@Guna所述(是,您可以创建缓存的线程池,并让执行器在线程上运行任务。

你可以像这样创建线程类

public class AsyncThread extends Thread{
        @Override
        public void run() {
            super.run();
            //do your task
        }
    }

并检查线程是否还活着

AsyncThread thread = new AsyncThread();
        if(thread.isAlive()){
            thread.interrupt();
           //do other stuff
        }else{
            thread.start();
        }

最新更新