Ivan
Ivan

Reputation: 361

Java - Threads runned with Executors.newFixedThreadPool are never finished

I have threads those should be finished, but did not do that. There is a stacktrace in each thread (checked with debugger):

Unsafe.park(boolean, long) line: not available [native method]  
LockSupport.park(Object) line: not available    
AbstractQueuedSynchronizer$ConditionObject.await() line: not available  
LinkedBlockingQueue<E>.take() line: not available   
ThreadPoolExecutor.getTask() line: not available    
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: not available 
ThreadPoolExecutor$Worker.run() line: not available 
Thread.run() line: not available    

The code:

ExecutorService threadExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
int totalNumberOfTasks = 0;
for(int i = 0; i < size; i++) {
    if(expr != null) {
        totalNumberOfTasks++;
        threadExecutor.execute(new Runnable() {

            @Override
            public void run() {
                doSmth();
            }
        });
    }
}
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks);
try {
    latch.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}

I also tried to use Semaphor instead of CountDownLatch, but had the same result. Can someone help me please?

Upvotes: 0

Views: 252

Answers (2)

flo
flo

Reputation: 10281

You are missing to count down the latch when a worker thread finishes. I wouldn't use the CountDownLatch at all but rely on the ExecutorService's shutdown and awaitTermination methods to wait for the threads to finish:

ExecutorService threadExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
for(int i = 0; i < size; i++) {
    if(expr != null) {
        threadExecutor.execute(new Runnable() {

            @Override
            public void run() {
                doSmth();
            }
        });
    }
}

threadExecutor.shutdown();
try {
    threadExecutor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
    // handle timeout
}

Upvotes: 0

Fildor
Fildor

Reputation: 16148

Try this:

ExecutorService threadExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

// Must be available in Runnables
final CountDownLatch latch = new CountDownLatch(size);

int totalNumberOfTasks = 0;
for(int i = 0; i < size; i++) {
    if(expr != null) {
        totalNumberOfTasks++;
        threadExecutor.execute(new Runnable() {

            @Override
            public void run() {
                doSmth();
                latch.countDown(); // Countdown the latch
            }
        });
    }
}

try {
    latch.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}

If you do not know the number of tasks beforehand, you could use invokeAll:

Executes the given tasks, returning a list of Futures holding their status and results when all complete.

Upvotes: 1

Related Questions