簡體   English   中英

Java:強制停止ExecutorService線程

[英]Java: Force stopping of ExecutorService threads

我的代碼:


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);
        }

但有時洪流下載需要未知的時間價值,« awaitTermination »不能按我的意願運行。 我需要在半小時后立即停止所有執行的線程,但據我所知« awaitTermination »只使用interrupt()方法,該方法僅在循環或等待中起作用。 如果這一刻發生,超時不起作用。 那么,怎么樣?

除非線程定期檢查isInterrupted()標志(或正在等待可中斷的方法,即拋出InterruptedException),否則永遠不會保證即時線程終止。

當他們定期檢查isInterrupted()時,請考慮以方式實現工作線程。 這可能是這樣的:

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

ExecutorService.shutdownNow()將嘗試停止所有正在執行的線程..

這是javadoc的引用

List<Runnable> shutdownNow()

嘗試停止所有正在執行的任務,停止等待任務的處理,並返回等待執行的任務列表。

除盡力嘗試停止處理主動執行任務之外,沒有任何保證。 例如,典型的實現將通過Thread.interrupt()取消,因此如果任何任務屏蔽或無法響應中斷,它們可能永遠不會終止。

由於下載torrent可能涉及阻止IO操作,因此僅調用cancel() / shutdownNow()是不夠的,因為阻止IO操作不能保證在各自的線程被中斷時終止。

您還需要關閉底層套接字以取消阻塞IO,請參閱如何立即終止套接字IO操作上的線程阻塞?

ExecutorService.submit(...)返回一個具有cancel()方法的Future<?> 您應該跟蹤這些可以在您希望每個任務停止時調用它們。

使用我創建的代碼。

它使用wkhtmltopdf從許多html模板生成許多pdf文件。

所以我想提高創建handreds的性能而不讓客戶端等待,這只是實現的一部分。

關於getListOfCallables它返回正確的最佳閾值,用於在固定池創建中使用的線程數。

所以我無法處理周圍有很多未死線程使我的EC2 CPU 100%卡住。

我用了 :

  • 關掉()
  • shutdownNow()在await的其他地方
  • 異常部分中的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);
            }

現在我必須從池中停止線程。 我是這樣做的。 這可能不是一個好主意。 請評論,如果是的話。

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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM