开发者

Java: Force stopping of ExecutorService threads

开发者 https://www.devze.com 2023-03-03 22:12 出处:网络
My code: String[] torrentFiles = new File(\"/root/torrents/\").list(); if(torrentFiles.length == 0 || torrentFiles == null)

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/" +开发者_JAVA技巧 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?


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


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.


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?.


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.


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


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

精彩评论

暂无评论...
验证码 换一张
取 消