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()第一个轮询线程上的code>是否也杀死我的子线程
如果否,如何在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]