Java cachedThreadPool kill submitted threads

I need to do multi-threaded work and I use ExecutorService.newCachedThreadPool()

and post some job received from the queue.

public class ContentParser {
    public static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    // ...

    public static void queueExecutor(Content content)  {
        String url = "";
        while ((url = queue.poll()) != null){
            LOG.info("Picked url " + url);
            cachedThreadPool.submit(new ParserCallable(content, url));
        }
    }

    // ...

private static class ParserCallable implements Runnable {
    private Content content;
    private String url;
    private ParserCallable(Content content, String url) {
        this.url = url;
        this.content = content;
    }

    @Override
    public void run(){
        new FontParser().fontSearcher(content, url);
    }
}

      

This way each thread creates a new instance FontParser

, and inside it I do some work.

I call mine ContentParser.queueExecutor

from another class, so after submitting all assignments I do:

ContentParser.cachedThreadPool.shutdown();
ContentParser.cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);

      

But it just kills my threads, even if the work is not finished and is not waiting.

Maybe because I am creating a new instance new FontParser().fontSearcher(content, url);

in each thread?

+3


source to share


1 answer


I am calling my ContentParser.queueExecutor from another class, so after submitting all the jobs, I do:

It looks like you are saying that someone is calling cachedThreadPool.shutdown()

, but jobs are still being submitted to the pool. This should never have happened. shutdown()

should only be called after the loop has finished poll()

.

I would recommend doing something like the following in your method queueExecutor(...)

:

while ((url = queue.poll()) != null){
    LOG.info("Picked url " + url);
    cachedThreadPool.submit(new ParserCallable(content, url));
}
// shutdown _after_ all jobs have been submitted
cachedThreadPool.shutdown();

      



Also, in general, it is bad practice to make fields public - especially in this case, your field cachedThreadPool

. You have no control over how (or in this case, when) external classes call critical methods in your pool. I would make it private and then the wait method in the class ContentParser

:

private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
...
public static void awaitPoolTermination(/* maybe timeout args here */) {
    cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);
}

      

This better controls the thread pool and prevents you from shutting down in the wrong place. So the caller ContentParser

will call first contentParser.queueExecutor(...)

and then call contentParser.awaitPoolTermination(...)

.

0


source







All Articles