java - ScheduledThreadPoolExecutor.remove : Is it safe to use

标签 java multithreading threadpool

我正在尝试安排一堆任务定期执行。在某些情况下,某些任务需要停止调度,因此我将它们从 threadPoolExecutor 的内部队列中删除。我从任务本身内部进行此操作

以下是我的方法。我不确定从任务内部从 threadPoolExecutor 服务中删除任务的想法会导致任何问题。(查看同步方法名称“removeTask”。是否有更好的方法来完成我在这里尝试做的事情。

public class SchedulerDaemon  {


    private ScheduledExecutorService taskScheduler;
    private ScheduledFuture taskResult1, taskResult2;
    private Task1 task1;
    private Task2 task2;


    public SchedulerDaemon(Task1 task, Task2 task2)
    {
        this.task1 = task1;
        this.task2 = task2;1
        taskScheduler = new ScheduledThreadPoolExecutor(1);
    }


    public void start() {
       if(taskScheduler == null) {
           taskScheduler = new ScheduledThreadPoolExecutor(1);
           taskResult = taskScheduler.scheduleAtFixedRate(new TaskWrapper(task1) , 60000,60000, TimeUnit.MILLISECONDS);
           taskResult2 = taskScheduler.scheduleAtFixedRate(new TaskWrapper(task2) , 60000,60000, TimeUnit.MILLISECONDS);

       }
    }


    public void stop() {
        if(taskScheduler != null) {
            taskScheduler.shutdown();
            taskResult1.cancel(false); 
            taskResult2.cancel(false);           
            taskScheduler = null;
            taskResult = null;
        }

    }

        public  synchronized void removeTask( TaskWrapper task){
            ((ScheduledThreadPoolExecutor) taskScheduler).remove(task);
        }

    class TaskWrapper implements Runnable {
        private Task myTask;

        public TaskWrapper(Task task) {
            myTask = task;
        }

        @Override
        public void run() {
            try {
               boolean keepRunningTask = myTask.call();
               if(!keepRunningTask) {

                   ***//Should this cause any problem??***
                   removeTask(this);
               }
            } catch (Exception e) {
                //the task threw an exception remove it from execution queue
                ***//Should this cause any problem??***
                removeTask(this);
            }
        }



    }
}


public Task1 implements Callable<Boolean> {

public Boolean call() {  
if(<something>)
return true;
else
return false;    
}
}



public Task2 implements Callable<Boolean> {

    public Boolean call() {  
    if(<something>)
    return true;
    else
    return false;    
    }
    }

最佳答案

每当您安排任务时

ScheduledFuture<?> future = schedulerService.scheduleAtFixedRate(new AnyTask());

返回 Future 对象。 使用此 Future 对象取消此任务。 试试这个

  future.cancel(true);

来自 JavaDocs

  /**
     * Attempts to cancel execution of this task.  This attempt will
     * fail if the task has already completed, has already been cancelled,
     * or could not be cancelled for some other reason. If successful,
     * and this task has not started when <tt>cancel</tt> is called,
     * this task should never run.  If the task has already started,
     * then the <tt>mayInterruptIfRunning</tt> parameter determines
     * whether the thread executing this task should be interrupted in
     * an attempt to stop the task.
     *
     * <p>After this method returns, subsequent calls to {@link #isDone} will
     * always return <tt>true</tt>.  Subsequent calls to {@link #isCancelled}
     * will always return <tt>true</tt> if this method returned <tt>true</tt>.
     *
     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
     * task should be interrupted; otherwise, in-progress tasks are allowed
     * to complete
     * @return <tt>false</tt> if the task could not be cancelled,
     * typically because it has already completed normally;
     * <tt>true</tt> otherwise
     */ 

关于java - ScheduledThreadPoolExecutor.remove : Is it safe to use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17688834/

相关文章:

通过执行器重用java线程

java - 维度对象的优点和缺点?

java - String.split 数组到另一个二维字符串数组

java - Eclipse 找不到我的主类

java - AsyncTask 中的 Runnable 是否会阻止服务/Activity ?它对我有用

java - 服务效率

java - 如何等待线程池中的所有作业完成?

java - RejectedExecutionException 后调用线程不会停止

java - 如何在两个坐标之间填充二维 boolean 数组?

c# - WCF 是否使用 ThreadPool 为 PerCall 服务创建新实例?