简体   繁体   中英

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?

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.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM