如何中断 ExecutorService 的线程

发布于 2025-01-05 22:00:27 字数 97 浏览 1 评论 0原文

当使用Executors.newSingleThreadExecutor()返回的ExecutorService时,如何中断它?

When using the ExecutorService returned by Executors.newSingleThreadExecutor(), how do I interrupt it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼眸里的那抹悲凉 2025-01-12 22:00:27

为此,您需要 submit() 将任务发送给 ExecutorService,而不是调用 execute()。当您执行此操作时,将返回一个可用于操作计划任务的 Future。特别是,您可以调用 cancel(true) 在关联的 Future 上中断当前正在执行的任务(或者如果任务尚未开始运行则完全跳过执行) 。

顺便说一下, Executors.newSingleThreadExecutor() 实际上是一个ExecutorService

In order to do this, you need to submit() a task to an ExecutorService, rather than calling execute(). When you do this, a Future is returned that can be used to manipulate the scheduled task. In particular, you can call cancel(true) on the associated Future to interrupt a task that is currently executing (or skip execution altogether if the task hasn't started running yet).

By the way, the object returned by Executors.newSingleThreadExecutor() is actually an ExecutorService.

玻璃人 2025-01-12 22:00:27

中断执行程序的内部管理线程的另一种方法是调用 ExecutorService 上的 shutdownNow(..) 方法。但请注意,与 @erickson 的解决方案相反,这将导致整个 ThreadPoolExecutor 变得不适合进一步使用。

我发现这种方法在不再需要 ExecutorService 的情况下特别有用,并且不需要继续关注 Future 实例(一个典型的例子是 exit(..) 应用程序的方法)。

来自 ExecutorService#shutdownNow(..) javadocs 的相关信息:

尝试停止所有正在执行的任务,停止处理
等待任务,并返回正在等待的任务列表
执行。

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

Another way to interrupt the executor's internally managed thread(s) is to call the shutdownNow(..) method on your ExecutorService. Note, however, that as opposed to @erickson's solution, this will result in the whole ThreadPoolExecutor becoming unfit for further use.

I find this approach particularly useful in cases where the ExecutorService is no longer needed and keeping tabs on the Future instances is otherwise unnecessary (a prime example of this being the exit(..) method of your application).

Relevant information from the ExecutorService#shutdownNow(..) javadocs:

Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.

There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt, so any task that fails to respond to
interrupts may never terminate.

就是爱搞怪 2025-01-12 22:00:27

一种正确的方法可能是为 ExecutorService 自定义/注入 ThreadFactory ,并从线程工厂中获取创建的线程的句柄,然后您可以安排一些任务来执行中断感兴趣的线程。

ThreadFactory 中覆盖方法 newThread 的演示代码部分:

ThreadFactory customThreadfactory new ThreadFactory() {

            public Thread newThread(Runnable runnable) {
                final Thread thread = new Thread(runnable);
                if (namePrefix != null) {
                    thread.setName(namePrefix + "-" + count.getAndIncrement());
                }
                if (daemon != null) {
                    thread.setDaemon(daemon);
                }
                if (priority != null) {
                    thread.setPriority(priority);
                }
                
                scheduledExecutorService.schedule(new Callable<String>() {
                    public String call() throws Exception {
                        System.out.println("Executed!");
                        thread.interrupt();
                        return "Called!";
                    }
                }, 5, TimeUnit.SECONDS);
                
                return thread;
            }

}

然后您可以使用下面的代码来构造您的 ExecutorService 实例:

ExecutorService executorService = Executors.newFixedThreadPool(3,
        customThreadfactory);

然后 5 秒后,中断信号将被发送到ExecutorService中的线程。

One proper way could be customizing/injecting the ThreadFactory for the ExecutorService and from within the thread factory, you got the handle of the thread created, then you can schedule some task to interrupt the thread being interested.

Demo code part for the overwrited method newThread in ThreadFactory:

ThreadFactory customThreadfactory new ThreadFactory() {

            public Thread newThread(Runnable runnable) {
                final Thread thread = new Thread(runnable);
                if (namePrefix != null) {
                    thread.setName(namePrefix + "-" + count.getAndIncrement());
                }
                if (daemon != null) {
                    thread.setDaemon(daemon);
                }
                if (priority != null) {
                    thread.setPriority(priority);
                }
                
                scheduledExecutorService.schedule(new Callable<String>() {
                    public String call() throws Exception {
                        System.out.println("Executed!");
                        thread.interrupt();
                        return "Called!";
                    }
                }, 5, TimeUnit.SECONDS);
                
                return thread;
            }

}

Then you can use below code to construct your ExecutorService instance:

ExecutorService executorService = Executors.newFixedThreadPool(3,
        customThreadfactory);

Then after 5 seconds, an interrupt signal will be sent to the threads in ExecutorService.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文