Find out if threads are still running in threadPool - java

I have following part of code:
protected ExecutorService parallelExecutor = Executors.newCachedThreadPool();
protected ExecutorService serialExecutor = Executors.newSingleThreadExecutor();
List<?> parallelCommands = new ArrayList<?>();
List<?> serialCommands = new ArrayList<?>();
List<Future<Boolean>> results = null;
LocalDateTime timed = LocalDateTime.now().plusSeconds(60);
results = parallelExecutor.invokeAll(parallelCommands);
results.addAll(serialExecutor.invokeAll(serialCommands));
Now I would like to check if both executors finish their job within a timeout or not:
while (LocalDateTime.now().isBefore(timed)) {
\\ here I need to check if meanwhile my threads finished
\\ if yes, break;}
How can I verify if the executors finished their job?

JDK documentation:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination-long-java.util.concurrent.TimeUnit-

Use a counter to keep track of each task that finishes. You can decrement and check by modifying tasks added to your task list or by using a CompletableFuture.
List<Callable<?>> tasks = ...
ExecutorService executor = ...
// Might want to add the size of your other task list as well
AtomicInteger counter = new AtomicInteger(tasks.size());
for (Callable<?> callable : tasks) {
results.add(executor.submit(new Callable() {
callable.call();
int value = counter.decrementAndGet();
if (value == 0) {
synchronized (this) {
OuterClass.this.notify();
}
}
});
}
long timed = System.currentTimeMillis();
synchronized (this) {
long timeLeft;
// Or however many millis your timeout is
while ((timeLeft = 60_000 - System.currentTimeMillis() - timed) > 0) {
this.wait(timeLeft);
}
}
What you want to do is wait until you run out of time on your main thread, while your tasks are executed by the executor. If a task finishes and it realizes that there are no tasks that haven't finished, it tells the waiting thread to continue. I use notify() instead of notifyAll() because no other threads should be waiting for this object except the main thread, but if you do have other threads, use the latter option.

Related

Will thread execution continues when waiting for Future of one thread

I want to know that when a program waits for Future object of one thread, will other threads continue their execution.
I have tried the below sample, it seems when my program is waiting for one thread, other threads are not continuing their execution. Please tell me whether this is correct or is there any issues with my code for handling threads.
ExecutorService executor = Executors.newFixedThreadPool(3);
for(int i=0; i<5 ;i++)
{
Worker w = new Worker();
Future<String> future = executor.submit(w);
while(!future.isDone())
{
//Wait
}
String s = future.get();
System.out.println(LocalDateTime.now()+" "+s);
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
Below is my worker class:
public class Worker implements Callable<String> {
#Override
public String call() throws Exception {
// TODO Auto-generated method stub
Thread.sleep(3000);
return Thread.currentThread().getName();
}
}
I am getting the below results(Added date time to show that the results are not parallel):
2019-01-04T16:34:22.647 pool-1-thread-1
2019-01-04T16:34:25.661 pool-1-thread-2
2019-01-04T16:34:28.673 pool-1-thread-3
2019-01-04T16:34:31.685 pool-1-thread-1
2019-01-04T16:34:34.699 pool-1-thread-2
The problem
You presented the code which from main thread perspective waits (2) for each execution before submitting new task (1). In other words: in main thread you submit the task, wait for complete execution in main thread and submit next task after.
ExecutorService executor = Executors.newFixedThreadPool(3);
for(int i=0; i<5 ;i++)
{
Worker w = new Worker();
Future<String> future = executor.submit(w); // (1)
while(!future.isDone()) // (2)
{
//Wait
}
String s = future.get();
System.out.println(LocalDateTime.now()+" "+s);
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
Solution
To solve the issue you should (from main thread perspective) submit all tasks without waiting and then wait for results from executor service.
Example: https://stackoverflow.com/a/49746114/1815881
You can construct all tasks then call invokeAll() in ExecutorService.

How to ensure the tasks in the pool should get finish before the program exits?

I am currently working on a multi threaded document similarity program. Simply put this extract of the program gets an object, passes it to a "hasher" method ,minhashes a value of the object and adds it to a list to be manipulated in order to test similarity .
My issue is that the main thread seems to advance to where I manipulate the list whilst the threads from the pool are still running and minhashing the object values,using println I could see that the program had ran till to the end but the threads were still executing in the run() method after.
How can I ensure that the tasks in the pool should get finished before the program advances?
int docCount = 2;
while (docCount > 0) {
try {
Shingle s = q.take();
if (s instanceof Poisin == false) {
pool.execute(new Runnable() {
#Override
public void run() {
System.out.println("DEBUG : currently in run()" + Thread.currentThread());
if (s.getDocumentId() == 1) {
list1.add(hasher(s));
} else if (s.getDocumentId() == 2) {
list2.add(hasher(s));
} else {
voidList.add(hasher(s));
}
}
});// Runnable
} else {
docCount--;
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("INteruppted exception " + e);
}
}
float k1 = list1.size();
float k2 = list2.size();
System.out.println("DEBUG : End of program" + Thread.currentThread());
How can I ensure that the tasks in the pool have completed before the
program advances?
Use to initiates an orderly shutdown in which previously submitted tasks are executed, you need to call below methods after submitting tasks to executor. Because, calling shutdown will reject any new task afterward.
pool.shutdown();
Then after
pool.awaitTermination(60, TimeUnit.SECONDS) // specify timeout here
On Oracle documentation page, it was very well documented with an example (copied) :
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Above, method will ensure, there are no new task submitted and will wait for atmost 60 seconds to finish all tasks.
Try shutting down the executor service and waiting for all the threads to terminate before trying to process your results.
<Submit work to thread pool>
..
executorService.shutdownNow();
executorService.awaitTermination();
..
<Process results from threads>

ExecutorService.awaitTermination runs into timeout despite active tasks

I have the following implementation:
final ExecutorService service = Executors.newFixedThreadPool(4);
final List<Callable> taskList = new LinkedList<>();
for (Path path : paths) {
final SomeCallable task = new SomeCallable(path);
taskList.add(task);
service.submit(task);
}
synchronized (this) {
try {
this.wait();
shutdown(service);
} catch (InterruptedException e) {
shutdown(service);
}
}
And the following shutdown(service) method:
protected void shutdown(final ExecutorService service) {
List<Runnable> abortedCallables = service.shutdownNow();
try {
if (!service.awaitTermination(2, TimeUnit.MINUTES)) {
System.out.println("timeout");
}
}
catch (InterruptedException e) {
// (Re-)cancel all Callables if current thread has been interrupted
service.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
My problem is the following: paths is a list of a lot of Path instances. All of these paths will undergo some processing within a SomeCallable instance. Usually, this thread waits until all paths have been successfully handled within their SomeCallable. Once all paths have been processed shutdown(service) will be called.
However, it may happen that this thread is interrupted and has to be shutdown immediately. Therefore, I call shutdown(service) within the catch-block. What is working is, that currently running SomeCallable-instances will be finished and none of the tasks within the ExecutorService's thread pool will be started. Nonetheless, awaitTermination always runs into the 2 minute timeout. Why is this?
I assumed that awaitTermination waits for currently active running tasks to terminate (hence, wait for a maximum of 4 tasks -> thread pool size). Two minutes - in my case - is more than enough time for the 4 tasks to finish. As by calling shutdownNow() no new tasks from the queue should be started I wonder why I still get the timeout.
Any ideas?

How to exit ExecutorService after all the threads have done their execution? [duplicate]

This question already has answers here:
How to properly shutdown java ExecutorService
(2 answers)
Closed 5 years ago.
This is the code which is working but I am specifying the wait time explicitly. Is there any way to exit ExecutorService when all the threads have completed their execution.
ExecutorService es = Executors.newCachedThreadPool();
{
for(final List<String> list:partitions){
es.execute(new Runnable() {
public void run() {
try{
System.out.println(list);
new CallAPI().make_call(list, access_token);
}catch(Exception e){
System.out.println(e);
}
}
});
Thread.sleep(5000);
}
boolean finshed = es.awaitTermination(15, TimeUnit.MINUTES);
es.shutdown();
boolean finshed = es.awaitTermination(15, TimeUnit.MINUTES);==>I am giving here wait time but I don't want this because I don't know when the thread will finish execution
use Future<?> f = executor.submit(new Runnable(...));
store the futures in a list
after the loop, iterate over the futures and call f.get()
This will block until all the tasks have been executed.
You can then call executor.shutdown().
It sounds like you want ExecutorService.invokeAll. All you have to do is convert your collection of lists to a collection of Callables.
List<Callable<String>> tasks = partitions.stream()
.map(list->{
System.out.println(list);
new CallAPI().make_call(list, access_token);
return "finished";
}).collect(Collectors.toList());
List<Future<String>> futures = es.invokeAll(tasks);
es.shutdown();
Then you have the futures, you can use them to check for exceptions, or if the task completed ok.
The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
boolean awaitTermination(long timeout, TimeUnit unit)
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
To terminate the ExecutorService when all tasks are finished, just call es.shutdown(). Your own thread will continue the execution, while the task-threads will process all queued tasks.
From Java Doc:
shutdown
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
You need awaitTermination, when you want to block your own thread.

Testing RejectedExecutionHandler in ThreadPoolExecutor

How i can make sure that my rejectedExecution method works
RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
logger.log(Level.INFO, "Name_[" + executorServiceName + "]: All threads busy, processing inline.");
r.run();
}
});
I would personally create a situation where my ExecutorService will always reject a task and check that this task has been called using a counter.
So for example my code could be something like that:
// A single threaded executor service that cannot have more than 1 task in its task queue
// such that I know that if I provide at least 3 tasks, at least 1 task will be rejected.
// Why 3? 1 task in the queue + 1 task executed by the thread of the pool
// = max of tasks that the pool can manage at a given time, so if I add 1 it will be
// rejected.
ExecutorService executor = new ThreadPoolExecutor(
1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1),
Executors.defaultThreadFactory(), myHandler
);
// My Counter
AtomicInteger counter = new AtomicInteger();
// Some arbitrary task that lasts long enough to make sure that at least 3
// tasks will be submitted that will increment my counter once completed
Runnable task = () -> {
try {
Thread.sleep(1_000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
counter.incrementAndGet();
}
};
try {
// Submit 3 tasks
executor.submit(task);
executor.submit(task);
executor.submit(task);
} finally {
// Shutdown the pool and wait until all the submitted tasks have been executed
executor.shutdown();
executor.awaitTermination(1L, TimeUnit.MINUTES);
}
// Ensure that we have 3 tasks that have been executed
assertEquals(3, counter.get());

Categories

Resources