Java-杀死通过scheduledExecutorService生成的所有父线程和子线程

Java-杀死通过scheduledExecutorService生成的所有父线程和子线程,java,multithreading,executorservice,threadpoolexecutor,scheduledexecutorservice,Java,Multithreading,Executorservice,Threadpoolexecutor,Scheduledexecutorservice,我有一个线程,它在服务启动时使用scheduledExecutorService以固定速率进行轮询(servlet的contextInitialized)。此线程再次使用scheduledExecutorService以固定速率生成线程,scheduledExecutorService是第一个轮询线程的子线程。将调用scheduledExecutorService.shutdownNow()是否也杀死我的子线程 如果否,如何在servlet的contextDestroyed上杀死所有父线程和子线

我有一个线程,它在服务启动时使用
scheduledExecutorService
以固定速率进行轮询(servlet的contextInitialized)。此线程再次使用scheduledExecutorService以固定速率生成线程,scheduledExecutorService是第一个轮询线程的子线程。将调用scheduledExecutorService.shutdownNow()是否也杀死我的子线程

如果否,如何在servlet的contextDestroyed上杀死所有父线程和子线程

谢谢

调用
shutdownNow()
将导致取消所有正在执行的线程,并将停止任何
Runnable
Callable
对象提交给执行器。任何已提交但未启动的
Runnable
Callable
对象都会在列表中返回(表示为
ScheduledFutureTask
实例)。在这种情况下,取消意味着池中执行
可运行
可调用
实例的每个
线程
都将被中断,并且
可运行
/
可调用
中会抛出一个
中断异常
。如果在无限循环中忽略或处理此异常,
Runnable
将永远继续执行,即使它已被执行器取消。引自"基本法":

除了尽最大努力尝试停止处理外,没有其他保证 积极执行任务。例如,典型的实现将 通过
Thread.interrupt()
取消,因此任何无法响应的任务 中断可能永远不会终止

如果您正在将子
可运行
(或
可调用
)对象提交给父
可运行
启动的同一执行器,则是,子
可运行
对象也将被取消。此外,只要它们在接收到
中断异常时停止执行,它们就会被“杀死”

例如,运行以下代码

public class ParentRunnable implements Runnable {

    private final static AtomicInteger CHILD_ID = new AtomicInteger(0);
    private final ScheduledExecutorService executor;

    public ParentRunnable(ScheduledExecutorService executor) {
        this.executor = executor;
    }

    @Override
    public void run() {

        try {
            System.out.println("Started parent");

            while (true) {
                ChildRunnable child = new ChildRunnable(getChildName());
                executor.schedule(child, 1, TimeUnit.SECONDS);
                System.out.println("Submitted " + child.getName());
                Thread.sleep(2000);
            }
        }
        catch (InterruptedException e) {
            System.out.println("Parent thread was interrupted and is stopping");
        }
    }

    private static String getChildName() {
        return "Child " + CHILD_ID.addAndGet(1);
    }
}

public class ChildRunnable implements Runnable {

    private final String name;

    public ChildRunnable(String name) {
        this.name = name;
    }

    @Override
    public void run() {

        try {
            System.out.println("Started " + name);

            while (true) {
                Thread.sleep(1000);
            }
        }
        catch (InterruptedException e) {
            System.out.println(name + " was interrupted and is stopping");
        }
    }

    public String getName() {
        return name;
    }
}

public class Main {

    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(5);
        executor.execute(new ParentRunnable(executor));
        Thread.sleep(10000);
        List<Runnable> unstartedRunnables = executor.shutdownNow();
        executor.awaitTermination(10, TimeUnit.SECONDS);
        System.out.println("Unstarted runnables: " + unstartedRunnables);
    }
}
上面的代码启动一个
ParentRunnable
,然后提交一个
ChildRunnable
,每秒钟启动一次,然后休眠2秒。每个
ChildRunnable
都只会休眠1秒,但是
ParentRunnable
ChildRunnable
都会响应
中断异常
,中断各自的无限循环并结束
Runnable
的执行。
main
方法启动
ParentRunnable
,让
ParentRunnable
执行10秒钟,使用
shutdownNow()
终止执行器,然后打印执行器尚未启动的
Runnable
对象

查看结果,我们可以看到4个
ChildRunnable
对象已经启动,并且在使用
shutdownNow()
关闭执行器时被取消,剩余的
ChildRunnable
返回到未启动的
可运行文件列表中(由
ScheduledFutureTask
对象表示)

该计划之所以有效,是因为以下假设:

  • ChildRunnable
    实例提交给与
    ParentRunnable
  • ParentRunnable
    ChildRunnable
    实例在收到
    InterruptedException

  • 有关更多信息,请参阅的第6节和第7节,并查阅。

    是什么阻止您实际运行和测试您所说的内容?
    Started parent
    Submitted Child 1
    Started Child 1
    Submitted Child 2
    Started Child 2
    Submitted Child 3
    Started Child 3
    Submitted Child 4
    Started Child 4
    Submitted Child 5
    Parent thread was interrupted and is stopping
    Child 3 was interrupted and is stopping
    Child 4 was interrupted and is stopping
    Child 2 was interrupted and is stopping
    Child 1 was interrupted and is stopping
    Unstarted runnables: [java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@46f5f779]