Java:强制停止 ExecutorService 线程

发布于 2024-11-06 06:47:24 字数 834 浏览 0 评论 0原文

我的代码:


String[] torrentFiles = new File("/root/torrents/").list();

        if(torrentFiles.length == 0 || torrentFiles == null)
        {
            System.exit(0);
        }

        ex = Executors.newFixedThreadPool(3);

        for(String torrentFile : torrentFiles)
        {
            ex.submit(new DownloadTorrent("/root/torrents/" + torrentFile));
        }

        ex.shutdown();

        try
        {
            ex.awaitTermination(30, TimeUnit.MINUTES);
        }
        catch(InterruptedException ex1)
        {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1);
        }

但有时 torrent 下载需要未知的时间值,并且 «awaitTermination» 无法按我想要的方式工作。我需要在半小时后立即停止所有已执行的线程,但据我所知,“awaitTermination”仅使用仅在循环或等待中工作的“interrupt()”方法。所以如果这一刻发生,超时就不起作用。那么,如何做呢?

My code:


String[] torrentFiles = new File("/root/torrents/").list();

        if(torrentFiles.length == 0 || torrentFiles == null)
        {
            System.exit(0);
        }

        ex = Executors.newFixedThreadPool(3);

        for(String torrentFile : torrentFiles)
        {
            ex.submit(new DownloadTorrent("/root/torrents/" + torrentFile));
        }

        ex.shutdown();

        try
        {
            ex.awaitTermination(30, TimeUnit.MINUTES);
        }
        catch(InterruptedException ex1)
        {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1);
        }

But sometimes torrent downloading takes unknown time value and «awaitTermination» not works as I want. I need to stop all executed threads instantly after half an hour but as I know «awaitTermination» just only use interrupt() method which works only in loops or waiting. So timeout not works if this moment happens. So, how to?

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

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

发布评论

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

评论(6

吖咩 2024-11-13 06:47:24

永远不能保证线程立即终止,除非线程定期检查 isInterrupted() 标志(或者在可中断方法中等待,即抛出 InterruptedException)。

当工作线程定期检查 isInterrupted() 时,请考虑以某种方式实现工作线程。这可能是这样的:

public void run() { 
  byte[] data;
  do {
     data = receiveDataChunk(timeout);
     processData(data);
  } while(!isInterrupted() && data != null);
}

Instant thread termination is never guaranteed, unless the thread checks periodically for isInterrupted() flag (or is waiting in interruptable method, i.e. which throws InterruptedException).

Consider implementing your worker threads in manner, when they check periodically for isInterrupted(). This may be something like that:

public void run() { 
  byte[] data;
  do {
     data = receiveDataChunk(timeout);
     processData(data);
  } while(!isInterrupted() && data != null);
}
旧情别恋 2024-11-13 06:47:24

ExecutorService.shutdownNow() 将尝试停止所有正在执行的线程。

这是 javadoc 的引用

列表<可运行> shutdownNow()

尝试主动阻止一切
执行任务,停止处理
等待任务的数量,并返回一个列表
正在等待的任务
执行。

没有任何保证
超出尽力阻止的范围
处理主动执行的任务。
例如,典型的实现
将通过 Thread.interrupt() 取消,所以
如果有任何任务被屏蔽或无法响应
打扰,他们可能永远不会
终止。

ExecutorService.shutdownNow() will try to stop all the executing threads..

Here is a quote from javadoc

List<Runnable> shutdownNow()

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
if any tasks mask or fail to respond
to interrupts, they may never
terminate.

吃素的狼 2024-11-13 06:47:24

由于下载 torrent 可能涉及阻塞 IO 操作,因此仅调用 cancel()/shutdownNow() 是不够的,因为阻塞 IO 操作不能保证在其终止时终止。相应的线程被中断。

您还需要关闭底层套接字以取消阻塞 IO,请参阅 如何立即终止阻塞在套接字IO操作上的线程?

Since downloading a torrent probably involves blocking IO operations, simply calling cancel()/shutdownNow() won't be enough, because blocking IO operations are not guaranteed to terminate when their respective threads are interrupted.

You also need to close the underlying sockets in order to cancel blocking IO, see How to terminate a thread blocking on socket IO operation instantly?.

无畏 2024-11-13 06:47:24

< code>ExecutorService.submit(...) 返回一个具有 cancel() 方法的 Future。您应该跟踪这些可以在您希望每个任务停止时调用它。

ExecutorService.submit(...) returns a Future<?> that has a cancel() method. You should keep track of these can call it when you want each task to stop.

鸩远一方 2024-11-13 06:47:24

正在使用我创建的这段代码。

它使用 wkhtmltopdf 从许多 html 模板生成许多 pdf 文件。

所以我想提高创建手红的性能而不让客户等待,这只是实现的一部分。

关于 getListOfCallables 它返回正确的最优值
创建固定池时使用的线程数阈值。

所以我无法处理周围有很多未死的线程,这使得我的 EC2
CPU 100% 卡住。

使用了:

  • shutdown()
  • shutdownNow() in else of wait
  • 我在异常部分中

shutdownNow()列表 fileGenerationHtmlToPdfList = getListOfCallables(paths, name, options);

            ExecutorService executorService = Executors.newFixedThreadPool(fileGenerationHtmlToPdfList.size());


            List<Future<ArrayList<File>>> futures = null;

            try {
                futures = executorService.invokeAll(fileGenerationHtmlToPdfList);
                try {
                    for(Future f: futures) {
                        files.addAll((ArrayList<File>)f.get());
                    }

                } catch (InterruptedException ex) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
                } catch (ExecutionException ex) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
            }

 executorService.shutdown();//try shutdown

            try {
                if (executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Done ShutDowned");
                } else {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException ex) {
                executorService.shutdownNow();
                Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
            }

Am Using this code i have created.

Its generating many pdf files from many html templates using wkhtmltopdf .

so i want to increase performance of creating handreds without keep client waiting, this is only one part of implementation.

About getListOfCallables its returning the correct optimal
threshold for # of threads to use in fixed pool creation.

So i cant handle having lots of un dead threads laying around it made my EC2
CPU 100% stuck.

I used :

  • shutdown()
  • shutdownNow() in else of await
  • shutdownNow() in exception part

List fileGenerationHtmlToPdfList = getListOfCallables(paths, name, options);

            ExecutorService executorService = Executors.newFixedThreadPool(fileGenerationHtmlToPdfList.size());


            List<Future<ArrayList<File>>> futures = null;

            try {
                futures = executorService.invokeAll(fileGenerationHtmlToPdfList);
                try {
                    for(Future f: futures) {
                        files.addAll((ArrayList<File>)f.get());
                    }

                } catch (InterruptedException ex) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
                } catch (ExecutionException ex) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
            }

 executorService.shutdown();//try shutdown

            try {
                if (executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Done ShutDowned");
                } else {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException ex) {
                executorService.shutdownNow();
                Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex);
            }
猫弦 2024-11-13 06:47:24

现在我必须停止池中的线程。我就是这样做的。这可能不是一个好主意。如果有的话请评论一下。

boolean isTerminated = mPoolThreads.isTerminated();
while (!isTerminated) {
    mPoolThreads.shutdownNow();
    isTerminated = mPoolThreads.isTerminated();
    Log.i(Constants.LOG_TAG, "Stop threads: the threads are not terminated yet");
}
Log.w(Constants.LOG_TAG, "Stop threads: Terminated");

Now I have to stop threads from a pool. I am doing it such a way. It may be not a good idea. Comment, please, if so.

boolean isTerminated = mPoolThreads.isTerminated();
while (!isTerminated) {
    mPoolThreads.shutdownNow();
    isTerminated = mPoolThreads.isTerminated();
    Log.i(Constants.LOG_TAG, "Stop threads: the threads are not terminated yet");
}
Log.w(Constants.LOG_TAG, "Stop threads: Terminated");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文