Clark
Clark

Reputation: 2213

Java: Force stopping of ExecutorService threads

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?

Upvotes: 7

Views: 36551

Answers (6)

SimonC
SimonC

Reputation: 6718

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.

Upvotes: 1

shareef
shareef

Reputation: 9581

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

Upvotes: 0

Maksim Dmitriev
Maksim Dmitriev

Reputation: 6209

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

Upvotes: -1

axtavt
axtavt

Reputation: 242786

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

Upvotes: 6

weekens
weekens

Reputation: 8292

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

Upvotes: 11

Manimaran Selvan
Manimaran Selvan

Reputation: 2266

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.

Upvotes: 6

Related Questions