Reputation: 361
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
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
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