7

我的代码:


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()仅在循环或等待中有效的方法。因此,如果这一刻发生,超时将不起作用。那么,怎么做?

4

6 回答 6

11

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

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

public void run() { 
  byte[] data;
  do {
     data = receiveDataChunk(timeout);
     processData(data);
  } while(!isInterrupted() && data != null);
}
于 2011-05-10T07:44:45.880 回答
6

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

这是来自 javadoc 的引用

List<Runnable> shutdownNow()

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

除了尽最大努力停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.interrupt() 取消,因此如果任何任务屏蔽或未能响应中断,它们可能永远不会终止。

于 2011-05-10T07:31:03.100 回答
6

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

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

于 2011-05-10T07:46:11.270 回答
1

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

于 2011-05-10T07:30:01.713 回答
0

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

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

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

关于getListOfCallables它返回正确的最佳阈值,以便在固定池创建中使用的线程数。

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

我用了 :

  • 关闭()
  • shutdownNow() 在 else 的等待中
  • 异常部分的 shutdownNow()

列出 fileGenerationHtmlToPdfList = getListOfCallables(路径、名称、选项);

            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);
            }
于 2017-09-05T13:11:14.910 回答
-1

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

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");
于 2013-01-19T16:30:57.850 回答