我想在按钮单击时执行一些长时间运行的任务,如果用户再次单击该按钮,当前任务将强制停止并将执行下一个任务?
我正在发布一个纯基于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();
}