-1

我有这样的代码:

public class SomeClass
{
    private ScheduledExecutorService executor;
    private ScheduledFuture<?> future;
    private Set<String> keys;
    private ConcurrentMap<String, Something> map;

    public void startTask()
    {
        future = executor.scheduleWithFixedDelay(new SomeTask(), ...);
    }

    public void stopTask()
    {
        future.cancel(true);
        map.clear();
    }

    private class SomeTask implements Runnable
    {
        @Override
        public void run()
        {
            for (String key : keys)
            {
                if (Thread.interrupted())
                {
                    break;
                }

                // Getting value...

                map.put(key, value);
            }
        }
    }
}

我想确保退出map时它是空的。 我正在考虑通过使用一些同步器让该方法等到任务退出,但是,我不确定哪个会更好。也可能有另一种更好的方法来做我需要的事情。stopTask

该任务只有一个实例,如果重要,可以在取消后重新安排。

4

1 回答 1

0

对于你的问题,我基本上有两个答案:

每当您调用future.cancel(true)executor.shutdownNow()调用interrupt()线程池中的一个任务或所有线程时。除了可以抛出的interrupt()方法之外,任何 Java 方法都会忽略InterruptedException,例如Thread.sleep(). 在您的情况下,“获取价值”并将该值放入地图的代码不会被中断。唯一可能的中断点是您对其进行编码的位置 - 或者,如果您调用任何用于获取值的方法可能会 throw InterruptedException

但是,您真的只想停止一项任务,而不是调度程序本身吗?我宁愿停止调度,而不是仅仅取消任务。这是我用来停止任何类型的线程池并等待所有任务完成的代码片段:

public void stopTask()
{
    executor.shutdownNow(); // Stops submitting new tasks and sends interrupt to running tasks

    // Wait for tasks to complete
    while(!executor.isTerminated()) try {
        executor.awaitTermination(1L, TimeUnit.MINUTES);
        if(!executor.isTerminated())
            System.out.println("Still waiting for scheduled tasks to finish");
    } catch(InterruptedException e) {}

    map.clear();
    System.out.println(map);
}

shutdownNow()确保调用当前正在运行的任务interrupt()

于 2013-08-08T07:38:31.520 回答