如何停止池中除最后一个任务之外的所有任务?

How to stop all tasks in the pool except last one?

我有一个固定的单线程池。当我提交新任务时,我想停止除最后一个线程之外的所有旧线程。

private class MyPool extends ThreadPoolExecutor {

    public MyPool(long keepAliveTime, TimeUnit unit,
            BlockingQueue<Runnable> workQueue) {
        super(1, 1, keepAliveTime, unit, workQueue);
    }

    public boolean isReady() {
        return semaphore;
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        // Iterate all existed task and stop
        Future<T> future = super.submit(task);
        return future;
    }

    private volatile boolean semaphore;

}

运行 任务代码:

private class MyTask implements Runnable {

    private volatile boolean isRun = true;
    private int id;

    public MyTask(int id) {
        this.id = id;
    }

    public void stop() {
        isRun = false;
    }

    @Override
    public void run() {
        try {
            System.out.println("Start " + id);
            if (isRun) {
                Thread.sleep(1000);
                System.out.println("Stop " + id);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }       
}

我创建了自己的 class,但它无法正常工作,因为信号量也会影响新任务。最好的方法是什么?

如果提交了新的 Callable,此 ThreadPoolExecutor 将终止 运行 线程:

class MyPool extends ThreadPoolExecutor {
    private volatile Thread activeThread = null;
    private static final Field FutureTask$runner;

    static {
        try {
            FutureTask$runner = FutureTask.class.getDeclaredField("runner");
            FutureTask$runner.setAccessible(true);
        } catch (NoSuchFieldException e) {
            throw new Error(e);
        }
    }

    private static Thread getThread(FutureTask<?> task) {
        try {
            return (Thread) FutureTask$runner.get(task);
        } catch (IllegalAccessException e) {
            throw new Error(e);
        }
    }

    public MyPool() {
        super(1, 1,
            //whatever here
            5000, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>());
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        if(activeThread != null) {
            activeThread.stop(); //kill
        }
        FutureTask<T> activeTask = (FutureTask<T>)super.submit(task);
        activeThread = getThread(activeTask); //steal thread reference for killing
        return activeTask;
    }
}