ArrayBlockingQueue NoSuchElementException - java

Just for learning, I have written the following code for custom thread pool referring and editing the code shown here.
As shown in the code I am using ArrayBlockingQueue for task queue.
Code:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class ThreadPoolService {
private final BlockingQueue<Runnable> taskQueue;
private final int corePoolSize;
private ThreadPoolService(int corePoolSize) {
this.corePoolSize = corePoolSize;
this.taskQueue = new ArrayBlockingQueue<>(corePoolSize);
ThreadPool[] threadPool = new ThreadPool[corePoolSize];
for (int i = 0; i < corePoolSize; i++) {
threadPool[i] = new ThreadPool();
threadPool[i].start();
}
}
public static ThreadPoolService newFixedThreadPool(int size) {
return new ThreadPoolService(size);
}
public void execute(Runnable task) {
try {
taskQueue.offer(task, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ThreadPool extends Thread {
Runnable task;
#Override
public void run() {
while (true) {
try {
while (!taskQueue.isEmpty()) {
task = taskQueue.remove();
task.run();
}
} catch (RuntimeException ex) {
ex.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ThreadPoolService pool = ThreadPoolService.newFixedThreadPool(10);
Runnable task1 = () -> {
System.out.println(" Wait for sometime: -> " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable task2 = () -> System.out.println(" Do Task 2 -> " + Thread.currentThread().getName());
Runnable task3 = () -> System.out.println(" Do Task 3 -> " + Thread.currentThread().getName());
Runnable task4 = () -> System.out.println(" Do Task 4 -> " + Thread.currentThread().getName());
List<Runnable> taskList = new ArrayList<>();
taskList.add(task1);
taskList.add(task2);
taskList.add(task3);
taskList.add(task4);
for (Runnable task : taskList) {
pool.execute(task);
}
}
}
This code runs fine sometimes and sometimes gives an error.
Success output:
Do Task 2 -> Thread-2
Wait for sometime: -> Thread-8
Do Task 3 -> Thread-6
Do Task 4 -> Thread-7
Failure output:
Do Task 4 -> Thread-3
Do Task 3 -> Thread-6
Wait for sometime: -> Thread-4
Do Task 2 -> Thread-7
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at com.interview.java.ThreadPoolService$ThreadPool.run(ThreadPoolService.java:43)
I see the reason for the error is the attempt to remove the element when the queue is empty. But it should not because i am doing queue empty check at line no 42 (while (!taskQueue.isEmpty())). What is wrong with code and also why it runs without error sometimes ?

Between the 'while' check and the actual removal, the queue could be modified by another Thread, possibly resulting in the error you mention. That's called a 'race condition'.
So in order to fix that you'll need a way to block the access to the queue by other threads, either by 'locking', using a 'synchronized' block with a shared lock object. Or simply by 'polling' instead of removing.

BlockingQueue is thread-safe only on an individual operation level.I'm seeing check-then-actoperation in the code which is a compound operation which is not thread-safe. To make this code thread-safe perform the check-then-act inside a synchronized block and lock on the queue itself.
synchronized(taskQueue) {
while (!taskQueue.isEmpty()) {
task = taskQueue.remove();
task.run();
}};
optimization: If the task is a time consuming one, you can execute it outside the synchronized block. So that other threads don't have to wait till the current task completes.

What is wrong with code?
You access taskQueue field from several threads without synchronization. You must do queue empty check and remove operation atomically, which can be done with synchronized keyword:
private class ThreadPool extends Thread {
#Override
public void run() {
Runnable task;
while (true) {
synchronized(queue) {
// give access to taskQueue to one thread at a time
if (!taskQueue.isEmpty()) {
task = taskQueue.remove();
}
}
try {
task.run();
} catch (RuntimeException ex) {
ex.printStackTrace();
}
}
}
}
why it runs without error sometimes?
Because of nature of JVM thread scheduler: sometimes it plans thread execution in such a way that they access taskQueue synchronously by themselves. But when you deal with multithreading, you can't rely on thread execution order, and must synchronize access to shared objects by yourself.

Related

Thread won't die and two of them keep overlapping

I need a thread that will only run once at a time, for example if it's called for the first time it will run, if it is called a second time, the first should stop completely and be allowed to die and a new one should take it's place.
I was ran a small test to see what was actually happening between each execution, the results show that the thread doesnt die but instead two threads are being executed alongside:
public class Test {
Worker worker = new Worker();
#Override
public void valid() {
try {
if (worker.running) {
worker.running = false;
worker.join();
}
} catch (InterruptedException iex) {
worker.running = false;
}
worker = new Worker();
worker.start();
}
private final class Worker extends Thread {
private volatile boolean running = true;
#Override
public void run() {
while (running) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException iex) {
Thread.currentThread().interrupt();
}
}
}
}
}
The results are as follows:
//Upon first execution
Thread-4
Thread-4
Thread-4
Thread-4
//When I execute it again
Thread-7
Thread-4
Thread-7
Thread-4
Thread-7
Thread-4
I've tried using ExecutorService or using while(!Thread.currentThread.isInterrupted) instead of the boolean flag, and got the same results.
How can I properly stop "Thread-4" and have only one of them running?
The actual issue comes from a thread that will cycle through a list and update things on discord chat by request, what the thread does is listen to input and change as suggested by kidney I'm trying to use executor.submit() and Future
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<Void> worker;
private void setupImageThread() {
if (!worker.isDone() && !worker.isCancelled()) {
worker.cancel(true);
}
this.worker = (Future<Void>)executor.submit(new Cycler(Listener.queue(), this.links, Cel.cMember()));
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable timeout = () -> {
executor.shutdown();
};
ses.schedule(timeout, 100, TimeUnit.SECONDS);
}
How can I go about initializing the Future for the first time it is created?
Using single thread executor service, I would try something like this:
public class Test {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> worker;
public Test() {
this.worker = executor.submit(new Worker());
}
#Override
public void valid() {
if (!worker.isDone() && !worker.isCancelled()) {
worker.cancel(true); // Depends on whether you want to interrupt or not
}
this.worker = executor.submit(new Worker());
}
}
And make Worker implement Runnable.
It seems that the method valid can be called several times simultaneously. That means, every of those calls will wait to end only for one thread (Worker), whereas, every of them creates its own Worker and you lose a pointer to it, so it impossible to stop bunch of new created workers.
You should make the valid method synchronized: synchronized void valid() it will prevent creating many workers:
#Override
synchronized public void valid() {
...
}
One more thing to say. You put the while loop outside the try-catch, which is wrong: if the tread gets interrupted, the interruption doesn't kill it, because next interation gets started, so it should be like that:
#Override
public void run() {
try {
while (running) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(2000);
}
catch (InterruptedException iex) {
//you don't need here Thread.currentThread().interrupt() call, because the thread has alredy been interrupted.
// The return statement here is also obsolete, I just use it as an example, but you can use empty braces.
return;
}
}
}

Method optimization in java

I'm new to Java. I'm trying to optimize following method:
public void myLongRunningMethod()
{
LongRunningOperation1();
LongRunningOperation2();
LongRunningOperation3();
Log.Info("completion message goes here.")
}
LongRunningOperation1(),LongRunningOperation2() and LongRunningOperation3() are independant of each other and the order of their completion does not matter.
But the log statement should be printed only after successful completion of all these method calls.
If I take the following approach, since its using a new thread, I believe the order of completion of methods wont be guarenteed.
public String myMethod()
{
Thread thread1 = new Thread(() -> {
LongRunningOperation1();
}).start();
Thread thread2 = new Thread(() -> {
LongRunningOperation2();
}).start();
Thread thread3 = new Thread(() -> {
LongRunningOperation3();
}).start();
Log.Info("completion message goes here.")
}
As comments are mentioning, the easiest is either calling join() on each of the 3 threads: thread1.join(); thread2.join(); thread3.join();
Or use a CountDownLatch though it is a touch more involved (but maybe more conceptually 'correct'):
latch = new CountDownLatch(3)
get each thread to do latch.countDown() after completing its task.
get the main thread to latch.await() - voila.
Instead of creating Threads manually it is much better to use ExecutorService API. Using ExecutorService you can submit long running operations and as result you will receive Future instance which will let you wait until operation will be completed.
See below example which shows the idea:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class Threads {
public static void main(String[] args) {
new Threads().myMethod();
}
private String myMethod() {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<?>> futures = new ArrayList<>(3);
futures.add(executor.submit(this::LongRunningOperation1));
futures.add(executor.submit(this::LongRunningOperation2));
futures.add(executor.submit(this::LongRunningOperation3));
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("All operations are finished!");
return "Done";
}
private void LongRunningOperation1() {
sleep(TimeUnit.SECONDS.toMillis(1));
System.out.println("LongRunningOperation1 is finished!");
}
private void LongRunningOperation2() {
sleep(TimeUnit.SECONDS.toMillis(2));
System.out.println("LongRunningOperation2 is finished!");
}
private void LongRunningOperation3() {
sleep(TimeUnit.SECONDS.toMillis(3));
System.out.println("LongRunningOperation3 is finished!");
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Above code prints:
LongRunningOperation1 is finished!
LongRunningOperation2 is finished!
LongRunningOperation3 is finished!
All operations are finished!

Java's ExecutorService.awaitTermination vs Future.get(<TimeOut>)

I am using ExecutorService and submitting 2 Callables.
Can you tell me what is the difference between using ExecutorService.awaitTermination vs using the Future.get() ?
I do not want the threads to keep running indefinitely, and also each Future's exception should not affect other thread's Future.
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<MyObject1> obj1 = null;
if (true) {
task1 = executor.submit(<Callable1>);
}
Future<MyObject2> obj2 = null;
if (<Condition>) {
task2 = executor.submit(<Callable2>);
}
executor.shutdown();
try {
executor.awaitTermination(TIMEOUT_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}finally {
if( !executor.isTerminated()) {
}
try {
executor.shutdownNow();
}catch(Exception e) {
}
}
MyObject1 myobj1 = null;
try {
myobj1 = task1 != null ? task1.get() : null;
} catch (InterruptedException | ExecutionException e) {
}
MyObject2 myobj2 = null;
try {
myobj2 = task2 != null ? task2.get() : null;
} catch (InterruptedException | ExecutionException e) {
}
Similarity between ExecutorService.awaitTermination and Future.get(<TimeOut>) is that both are blocking in nature. Suppose you have called any of these methods in thread T then T will be blocked until condition associated with each is fulfilled.
In case of ExecutorService.awaitTermination, thread will be blocked until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first. Read docs. While in case of Future.get(<TimeOut>) thread will be blocked until the task is submitted and result is returned or an exception occured etc. Read docs.
Difference between them is "usability" of each and key driver for that is as mentioned below:
ExecutorService.awaitTermination
Should be use when you want to block the thread and do wish to proceed further until a specified time is elapsed (that is the time you will specify in awaitTermination(long timeout, TimeUnit unit)) Typically people either specify value like Long.MAX_VALUE so as to wait too long or smaller values which they think as per their business requirement, for example if I am waiting for response to be committed to GUI then I may not wait more than 5 minutes.
Should be used when you do not care about the results returned by the threads executing tasks.
Should be used when you do not want to wait infinitely for tasks to finish, and want to specify some threshold time.
Future.get(<TimeOut>)
Key difference between this and later is that you should use it when you want the thread to return the results and until that happens you want to keep the thread blocked and do not want to proceed further, and that's the reason you will use Callable when submitting the tasks. So, when you call Future.get(<TimeOut>) then thread will be blocked until results are returned by the thread or some exception occurs in the executing thread.
Refer below sample code I have created to demonstrate the usability of each, I have provided inline code comments to better explanation.
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ExecutorServiceFutureAndAwaitTermincationExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
testFutureGet(); // after testing comment out this and uncomment below
//testAwaitTermination();
}
private static void testAwaitTermination() throws InterruptedException {
List<Future<String>> futuresList = new ArrayList<>();
final ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask1 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(2000, true);
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask2 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(1000, true);
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask3 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(3000, true);
System.out.println("### Starting submitting tasks");
// submit the callable and register the returned future object so that it can be processed later.
futuresList.add(executorService.submit(callableTask1));
futuresList.add(executorService.submit(callableTask2));
futuresList.add(executorService.submit(callableTask3));
executorService.shutdown();
System.out.println("### Finished submitting tasks and shutdown executorService " + new Date());
executorService.awaitTermination(1, TimeUnit.SECONDS); // try this with 10 seconds and you will see after 3 seconds it reaches next line
// uncomment below and comment out above.
/*new Thread(){
public void run() {
try {
System.out.println("###" + new Date());
executorService.awaitTermination(1, TimeUnit.SECONDS); // try this with 10 seconds and you will see after 3 seconds it reaches next line
System.out.println("###" + new Date());
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();*/
System.out.println("### Finished. " + new Date());
}
private static void testFutureGet() throws InterruptedException, ExecutionException {
List<Future<String>> futuresList = new ArrayList<>();
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask1 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(2000, false);
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask2 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(1000, false);
ExecutorServiceFutureAndAwaitTermincationExample.CallableTask callableTask3 = new ExecutorServiceFutureAndAwaitTermincationExample.CallableTask(3000, false);
System.out.println("### Starting submitting tasks");
// submit the callable and register the returned future object so that it can be processed later.
futuresList.add(executorService.submit(callableTask1));
futuresList.add(executorService.submit(callableTask2));
futuresList.add(executorService.submit(callableTask3));
executorService.shutdown();
System.out.println("### Finished submitting tasks and shutdown executorService");
for (int i = 0; i < futuresList.size(); i++) {
// here "get()" waits for the future tasks to be returned.
System.out.println(futuresList.get(i).get());
}
System.out.println("### Finished.");
}
static class CallableTask implements Callable<String>{
private long timeToSleep;
private boolean shouldLog;
CallableTask(long _timeToSleep, boolean _shouldLog){
this.timeToSleep = _timeToSleep;
this.shouldLog = _shouldLog;
}
#Override
public String call() throws Exception {
String str = new Date() + ": Processing - " + this.hashCode() + " | " + Thread.currentThread() + ", slept for seconds - " + timeToSleep;
System.out.println(str);
Thread.sleep(timeToSleep);
if(this.shouldLog){
System.out.println(str + " ||||| completed at: " + new Date());
}
return str + " ||||| completed at: " + new Date();
}
}
}
And for your point:
I do not want the threads to keep running indefinitely, and also each
Future's exception should not affect other thread's Future.
ExecutorService.awaitTermination and Future.get(<TimeOut>) are not meant to control whether threads (which are processing your tasks) will run indefinitely or not, threads will run until the task they are performing is finished and run method of the thread is finished to completion. And I have explained the purpose of ExecutorService.awaitTermination and Future.get(<TimeOut>) above. And typically exception in one thread will not affect another thread, unless you are doing something which interrupt/affects other threads.
Can you tell me what is the difference between using ExecutorService.awaitTermination vs using the Future.get() ?
ExecutorService.awaitTermination() should only be called after an ExecutorService.shutdown() request. The spec doesn't define behavior if awaitTermination is called before shutdown. But in a nutshell, awaitTermination should only be used if you are intending to throw away the ExecutorService and never use it again. The Java EE Concurrency spec actually rejects applications calling this method. Overall, this doesn't look like the right option for your use case.
Future.get(Timeout) is for waiting for a specific Future to complete, and has nothing to do with wanting to shutdown the ExecutorService that the future is running in.
Also related, see this answer:
How to check if all tasks running on ExecutorService are completed
Futire.get waits for task to complete. ExecutorService.awaitTermination waits for executor service to be stopped. Usually, you should create Executor once and reuse it until application shutdown.
You may want to use Fuitire.get with timeout then cancel a future, if task was not completed. In this case other tasks will not be affected:
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Future task = executor.submit(() -> {
Thread.sleep(200);
return "1";
});
// later in time...
try {
Object result = task.get(150, TimeUnit.MILLISECONDS);
System.out.println("result = " + result);
} catch (InterruptedException e) {
System.out.println("Task interrupted");
} catch (ExecutionException e) {
System.out.println("Task execution failed");
} catch (TimeoutException e) {
System.out.println("Task timed-out. isDone=" + task.isDone() + ", isCancelled=" + task.isCancelled());
// cancel long-running task if you want to save resources
task.cancel(true);
System.out.println("Task Cancelled. isDone=" + task.isDone() + ", isCancelled=" + task.isCancelled());
}
// no more need for executor
System.out.println("Shutting down executor");
executor.shutdown();
}
}
Output:
Task timed-out. isDone=false, isCancelled=false
Task Cancelled. isDone=true, isCancelled=true
Shutting down executor

Java ExecutorService - why does this program keep running?

I'm trying to build something like a background task executor which terminates background tasks after a certain time if there's no answer (background tasks call webservices and they can time-out but I need to make sure they time out under a certain time)
So I have this as an experiment but if I run this the program does not terminate. I wonder if its because a background thread is still active maybe? How can I shut this down?
public class Test {
public static class Task implements Callable<Object> {
#Override
public Object call() throws Exception {
while(true) {}
}
}
public static void main(String[] args) {
try {
Task t = new Task();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(t), 5L, TimeUnit.SECONDS);
executor.shutdown();
System.out.println("DONE");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The ExecutorService does not kill the running threads, and since threads are created as non-daemon, the JVM doesn't exit.
What happens is that when timeout expires, futures returned by invokeAll() are cancelled, which means that a flag is set on the future object and you get a CancellationException if you try to call future.get(). However neither invokeAll(), nor shutdown() (or shutdownNow()) do anything to kill the thread.
Note that you cannot even kill threads yourself. All you can do is setting some application-specific flag or call Thread.interrupt(), but even that does not guarantee that the thread terminates.
There is a great post by Winterbe on how executors work. This is an excerpt from his tutorial
So basically executors always keep listening to the new tasks or callables/runnables and one way to shutdown the executor or stop the executor from listening is to interrupt whatever task it is executing. One way to do is calling the future.get() which stops when the main thread , suspends it and makes sure that the current thread gets executed completely before handing over the resource to other thread
You could probably have a higher number of threads and write your code to shutdown gracefully in the InterruptedException block
Here is a sample code that I've written and tested:
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ExecutorTest {
public static void main(String[] args) {
ExecutorService service = Executors.newWorkStealingPool(10);
Callable<AccountClass> newInstance = () -> {
TimeUnit.SECONDS.sleep(3);
return getAcc(Thread.currentThread().getId());
};
// for now only one instance is added to the list
// List<Callable<AccountClass>> callablesSingleList = Arrays.asList(newInstance);
// adding multipleCallalbes
List<Callable<AccountClass>> callablesMultipleList = Arrays.asList(
() -> {
TimeUnit.SECONDS.sleep(3);
return getAcc(Thread.currentThread().getId());
},
() -> {
TimeUnit.SECONDS.sleep(3);
return getAcc(Thread.currentThread().getId());
},
() -> {
TimeUnit.SECONDS.sleep(3);
return getAcc(Thread.currentThread().getId());
});
try {
service.invokeAll(callablesMultipleList).stream().map(future -> {
AccountClass fuClass = null;
try {
fuClass = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return fuClass;
}).forEach(getValue -> {
System.out.println("retunred value:" + getValue);
});
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
private static AccountClass getAcc(long itr) {
// probably call DB for every new thread iterator
System.out.println("getting the current thread" + itr);
AccountClass ac = new AccountClass();
ac.setId(itr);
ac.setName("vv");
ac.setRole("admin");
System.out.println("sending the accnt class:" + ac);
return ac;
}
}
UPDATE:
Another way of shutting down the executor is using the service.shutDownNow() - > which shutdowns the program even if its the middle of execution. You could use awaitTermination method to specify if you feel that it might take a few minutes to complete execution and then probably shutdown the service
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ExecutorScheduleFixedRate {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
Runnable task = () -> {
getAcc(33);
};
service.scheduleWithFixedDelay(task, 10, 5, TimeUnit.SECONDS);
if (!service.isShutdown()) {
List<Runnable> list2 = service.shutdownNow();
System.out.println(list2);
System.out.println("is shutdonw" + service.isShutdown());
System.out.println("Do something after the thread execution");
}
}
private static AccountClass getAcc(long itr) {
// probably call DB for every new thread iterator
System.out.println("getting the current thread" + itr);
AccountClass ac = new AccountClass();
ac.setId(itr);
ac.setName("vv");
ac.setRole("admin");
System.out.println("sending the accnt class:" + ac);
return ac;
}
}

How to wait for all threads to finish, using ExecutorService?

I need to execute some amount of tasks 4 at a time, something like this:
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
//...wait for completion somehow
How can I get notified once all of them are complete? For now I can't think about anything better than setting some global task counter and decrease it at the end of every task, then monitor in infinite loop this counter to become 0; or get a list of Futures and in infinite loop monitor isDone for all of them. What are better solutions not involving infinite loops?
Thanks.
Basically on an ExecutorService you call shutdown() and then awaitTermination():
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
Use a CountDownLatch:
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
try {
latch.await();
} catch (InterruptedException E) {
// handle
}
and within your task (enclose in try / finally)
latch.countDown();
ExecutorService.invokeAll() does it for you.
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
List<Callable<?>> tasks; // your tasks
// invokeAll() returns when all tasks are complete
List<Future<?>> futures = taskExecutor.invokeAll(tasks);
You can use Lists of Futures, as well:
List<Future> futures = new ArrayList<Future>();
// now add to it:
futures.add(executorInstance.submit(new Callable<Void>() {
public Void call() throws IOException {
// do something
return null;
}
}));
then when you want to join on all of them, its essentially the equivalent of joining on each, (with the added benefit that it re-raises exceptions from child threads to the main):
for(Future f: this.futures) { f.get(); }
Basically the trick is to call .get() on each Future one at a time, instead of infinite looping calling isDone() on (all or each). So you're guaranteed to "move on" through and past this block as soon as the last thread finishes. The caveat is that since the .get() call re-raises exceptions, if one of the threads dies, you would raise from this possibly before the other threads have finished to completion [to avoid this, you could add a catch ExecutionException around the get call]. The other caveat is it keeps a reference to all threads so if they have thread local variables they won't get collected till after you get past this block (though you might be able to get around this, if it became a problem, by removing Future's off the ArrayList). If you wanted to know which Future "finishes first" you could use some something like https://stackoverflow.com/a/31885029/32453
In Java8 you can do it with CompletableFuture:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Runnable> tasks = getTasks();
CompletableFuture<?>[] futures = tasks.stream()
.map(task -> CompletableFuture.runAsync(task, es))
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).join();
es.shutdown();
Just my two cents.
To overcome the requirement of CountDownLatch to know the number of tasks beforehand, you could do it the old fashion way by using a simple Semaphore.
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
int numberOfTasks=0;
Semaphore s=new Semaphore(0);
while(...) {
taskExecutor.execute(new MyTask());
numberOfTasks++;
}
try {
s.aquire(numberOfTasks);
...
In your task just call s.release() as you would latch.countDown();
A bit late to the game but for the sake of completion...
Instead of 'waiting' for all tasks to finish, you can think in terms of the Hollywood principle, "don't call me, I'll call you" - when I'm finished.
I think the resulting code is more elegant...
Guava offers some interesting tools to accomplish this.
An example:
Wrap an ExecutorService into a ListeningExecutorService:
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
Submit a collection of callables for execution ::
for (Callable<Integer> callable : callables) {
ListenableFuture<Integer> lf = service.submit(callable);
// listenableFutures is a collection
listenableFutures.add(lf)
});
Now the essential part:
ListenableFuture<List<Integer>> lf = Futures.successfulAsList(listenableFutures);
Attach a callback to the ListenableFuture, that you can use to be notified when all futures complete:
Futures.addCallback(lf, new FutureCallback<List<Integer>> () {
#Override
public void onSuccess(List<Integer> result) {
// do something with all the results
}
#Override
public void onFailure(Throwable t) {
// log failure
}
});
This also offers the advantage that you can collect all the results in one place once the processing is finished...
More information here
The CyclicBarrier class in Java 5 and later is designed for this sort of thing.
here is two options , just bit confuse which one is best to go.
Option 1:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Runnable> tasks = getTasks();
CompletableFuture<?>[] futures = tasks.stream()
.map(task -> CompletableFuture.runAsync(task, es))
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).join();
es.shutdown();
Option 2:
ExecutorService es = Executors.newFixedThreadPool(4);
List< Future<?>> futures = new ArrayList<>();
for(Runnable task : taskList) {
futures.add(es.submit(task));
}
for(Future<?> future : futures) {
try {
future.get();
}catch(Exception e){
// do logging and nothing else
}
}
es.shutdown();
Here putting future.get(); in try catch is good idea right?
Follow one of below approaches.
Iterate through all Future tasks, returned from submit on ExecutorService and check the status with blocking call get() on Future object as suggested by Kiran
Use invokeAll() on ExecutorService
CountDownLatch
ForkJoinPool or Executors.html#newWorkStealingPool
Use shutdown, awaitTermination, shutdownNow APIs of ThreadPoolExecutor in proper sequence
Related SE questions:
How is CountDownLatch used in Java Multithreading?
How to properly shutdown java ExecutorService
You could wrap your tasks in another runnable, that will send notifications:
taskExecutor.execute(new Runnable() {
public void run() {
taskStartedNotification();
new MyTask().run();
taskFinishedNotification();
}
});
Clean way with ExecutorService
List<Future<Void>> results = null;
try {
List<Callable<Void>> tasks = new ArrayList<>();
ExecutorService executorService = Executors.newFixedThreadPool(4);
results = executorService.invokeAll(tasks);
} catch (InterruptedException ex) {
...
} catch (Exception ex) {
...
}
I've just written a sample program that solves your problem. There was no concise implementation given, so I'll add one. While you can use executor.shutdown() and executor.awaitTermination(), it is not the best practice as the time taken by different threads would be unpredictable.
ExecutorService es = Executors.newCachedThreadPool();
List<Callable<Integer>> tasks = new ArrayList<>();
for (int j = 1; j <= 10; j++) {
tasks.add(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
int sum = 0;
System.out.println("Starting Thread "
+ Thread.currentThread().getId());
for (int i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("Stopping Thread "
+ Thread.currentThread().getId());
return sum;
}
});
}
try {
List<Future<Integer>> futures = es.invokeAll(tasks);
int flag = 0;
for (Future<Integer> f : futures) {
Integer res = f.get();
System.out.println("Sum: " + res);
if (!f.isDone())
flag = 1;
}
if (flag == 0)
System.out.println("SUCCESS");
else
System.out.println("FAILED");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
Just to provide more alternatives here different to use latch/barriers.
You can also get the partial results until all of them finish using CompletionService.
From Java Concurrency in practice:
"If you have a batch of computations to submit to an Executor and you want to retrieve their results as they become
available, you could retain the Future associated with each task and repeatedly poll for completion by calling get with a
timeout of zero. This is possible, but tedious. Fortunately there is a better way: a completion service."
Here the implementation
public class TaskSubmiter {
private final ExecutorService executor;
TaskSubmiter(ExecutorService executor) { this.executor = executor; }
void doSomethingLarge(AnySourceClass source) {
final List<InterestedResult> info = doPartialAsyncProcess(source);
CompletionService<PartialResult> completionService = new ExecutorCompletionService<PartialResult>(executor);
for (final InterestedResult interestedResultItem : info)
completionService.submit(new Callable<PartialResult>() {
public PartialResult call() {
return InterestedResult.doAnOperationToGetPartialResult();
}
});
try {
for (int t = 0, n = info.size(); t < n; t++) {
Future<PartialResult> f = completionService.take();
PartialResult PartialResult = f.get();
processThisSegment(PartialResult);
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
throw somethinghrowable(e.getCause());
}
}
}
This is my solution, based in "AdamSkywalker" tip, and it works
package frss.main;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestHilos {
void procesar() {
ExecutorService es = Executors.newFixedThreadPool(4);
List<Runnable> tasks = getTasks();
CompletableFuture<?>[] futures = tasks.stream().map(task -> CompletableFuture.runAsync(task, es)).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).join();
es.shutdown();
System.out.println("FIN DEL PROCESO DE HILOS");
}
private List<Runnable> getTasks() {
List<Runnable> tasks = new ArrayList<Runnable>();
Hilo01 task1 = new Hilo01();
tasks.add(task1);
Hilo02 task2 = new Hilo02();
tasks.add(task2);
return tasks;
}
private class Hilo01 extends Thread {
#Override
public void run() {
System.out.println("HILO 1");
}
}
private class Hilo02 extends Thread {
#Override
public void run() {
try {
sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("HILO 2");
}
}
public static void main(String[] args) {
TestHilos test = new TestHilos();
test.procesar();
}
}
You could use this code:
public class MyTask implements Runnable {
private CountDownLatch countDownLatch;
public MyTask(CountDownLatch countDownLatch {
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
try {
//Do somethings
//
this.countDownLatch.countDown();//important
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
CountDownLatch countDownLatch = new CountDownLatch(NUMBER_OF_TASKS);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
for (int i = 0; i < NUMBER_OF_TASKS; i++){
taskExecutor.execute(new MyTask(countDownLatch));
}
countDownLatch.await();
System.out.println("Finish tasks");
So I post my answer from linked question here, incase someone want a simpler way to do this
ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture[] futures = new CompletableFuture[10];
int i = 0;
while (...) {
futures[i++] = CompletableFuture.runAsync(runner, executor);
}
CompletableFuture.allOf(futures).join(); // THis will wait until all future ready.
I created the following working example. The idea is to have a way to process a pool of tasks (I am using a queue as example) with many Threads (determined programmatically by the numberOfTasks/threshold), and wait until all Threads are completed to continue with some other processing.
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** Testing CountDownLatch and ExecutorService to manage scenario where
* multiple Threads work together to complete tasks from a single
* resource provider, so the processing can be faster. */
public class ThreadCountDown {
private CountDownLatch threadsCountdown = null;
private static Queue<Integer> tasks = new PriorityQueue<>();
public static void main(String[] args) {
// Create a queue with "Tasks"
int numberOfTasks = 2000;
while(numberOfTasks-- > 0) {
tasks.add(numberOfTasks);
}
// Initiate Processing of Tasks
ThreadCountDown main = new ThreadCountDown();
main.process(tasks);
}
/* Receiving the Tasks to process, and creating multiple Threads
* to process in parallel. */
private void process(Queue<Integer> tasks) {
int numberOfThreads = getNumberOfThreadsRequired(tasks.size());
threadsCountdown = new CountDownLatch(numberOfThreads);
ExecutorService threadExecutor = Executors.newFixedThreadPool(numberOfThreads);
//Initialize each Thread
while(numberOfThreads-- > 0) {
System.out.println("Initializing Thread: "+numberOfThreads);
threadExecutor.execute(new MyThread("Thread "+numberOfThreads));
}
try {
//Shutdown the Executor, so it cannot receive more Threads.
threadExecutor.shutdown();
threadsCountdown.await();
System.out.println("ALL THREADS COMPLETED!");
//continue With Some Other Process Here
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
/* Determine the number of Threads to create */
private int getNumberOfThreadsRequired(int size) {
int threshold = 100;
int threads = size / threshold;
if( size > (threads*threshold) ){
threads++;
}
return threads;
}
/* Task Provider. All Threads will get their task from here */
private synchronized static Integer getTask(){
return tasks.poll();
}
/* The Threads will get Tasks and process them, while still available.
* When no more tasks available, the thread will complete and reduce the threadsCountdown */
private class MyThread implements Runnable {
private String threadName;
protected MyThread(String threadName) {
super();
this.threadName = threadName;
}
#Override
public void run() {
Integer task;
try{
//Check in the Task pool if anything pending to process
while( (task = getTask()) != null ){
processTask(task);
}
}catch (Exception ex){
ex.printStackTrace();
}finally {
/*Reduce count when no more tasks to process. Eventually all
Threads will end-up here, reducing the count to 0, allowing
the flow to continue after threadsCountdown.await(); */
threadsCountdown.countDown();
}
}
private void processTask(Integer task){
try{
System.out.println(this.threadName+" is Working on Task: "+ task);
}catch (Exception ex){
ex.printStackTrace();
}
}
}
}
Hope it helps!
You could use your own subclass of ExecutorCompletionService to wrap taskExecutor, and your own implementation of BlockingQueue to get informed when each task completes and perform whatever callback or other action you desire when the number of completed tasks reaches your desired goal.
you should use executorService.shutdown() and executorService.awaitTermination method.
An example as follows :
public class ScheduledThreadPoolExample {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
executorService.scheduleAtFixedRate(() -> System.out.println("process task."),
0, 1, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(10);
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
}
}
if you use more thread ExecutionServices SEQUENTIALLY and want to wait EACH EXECUTIONSERVICE to be finished. The best way is like below;
ExecutorService executer1 = Executors.newFixedThreadPool(THREAD_SIZE1);
for (<loop>) {
executer1.execute(new Runnable() {
#Override
public void run() {
...
}
});
}
executer1.shutdown();
try{
executer1.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
ExecutorService executer2 = Executors.newFixedThreadPool(THREAD_SIZE2);
for (true) {
executer2.execute(new Runnable() {
#Override
public void run() {
...
}
});
}
executer2.shutdown();
} catch (Exception e){
...
}
Try-with-Resources syntax on AutoCloseable executor service with Project Loom
Project Loom seeks to add new features to the concurrency abilities in Java.
One of those features is making the ExecutorService AutoCloseable. This means every ExecutorService implementation will offer a close method. And it means we can use try-with-resources syntax to automatically close an ExecutorService object.
The ExecutorService#close method blocks until all submitted tasks are completed. Using close takes the place of calling shutdown & awaitTermination.
Being AutoCloseable contributes to Project Loom’s attempt to bring “structured concurrency” to Java.
try (
ExecutorService executorService = Executors.… ;
) {
// Submit your `Runnable`/`Callable` tasks to the executor service.
…
}
// At this point, flow-of-control blocks until all submitted tasks are done/canceled/failed.
// After this point, the executor service will have been automatically shutdown, wia `close` method called by try-with-resources syntax.
For more information on Project Loom, search for talks and interviews given by Ron Pressler and others on the Project Loom team. Focus on the more recent, as Project Loom has evolved.
Experimental builds of Project Loom technology are available now, based on early-access Java 18.
Java 8 - We can use stream API to process stream. Please see snippet below
final List<Runnable> tasks = ...; //or any other functional interface
tasks.stream().parallel().forEach(Runnable::run) // Uses default pool
//alternatively to specify parallelism
new ForkJoinPool(15).submit(
() -> tasks.stream().parallel().forEach(Runnable::run)
).get();
ExecutorService WORKER_THREAD_POOL
= Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
WORKER_THREAD_POOL.submit(() -> {
try {
// doSomething();
latch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// wait for the latch to be decremented by the two remaining threads
latch.await();
If doSomething() throw some other exceptions, the latch.countDown() seems will not execute, so what should I do?
This might help
Log.i(LOG_TAG, "shutting down executor...");
executor.shutdown();
while (true) {
try {
Log.i(LOG_TAG, "Waiting for executor to terminate...");
if (executor.isTerminated())
break;
if (executor.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
break;
}
} catch (InterruptedException ignored) {}
}
You could call waitTillDone() on this Runner class:
Runner runner = Runner.runner(4); // create pool with 4 threads in thread pool
while(...) {
runner.run(new MyTask()); // here you submit your task
}
runner.waitTillDone(); // and this blocks until all tasks are finished (or failed)
runner.shutdown(); // once you done you can shutdown the runner
You can reuse this class and call waitTillDone() as many times as you want to before calling shutdown(), plus your code is extremly simple. Also you don't have to know the number of tasks upfront.
To use it just add this gradle/maven compile 'com.github.matejtymes:javafixes:1.3.1' dependency to your project.
More details can be found here:
https://github.com/MatejTymes/JavaFixes
There is a method in executor getActiveCount() - that gives the count of active threads.
After spanning the thread, we can check if the activeCount() value is 0. Once the value is zero, it is meant that there are no active threads currently running which means task is finished:
while (true) {
if (executor.getActiveCount() == 0) {
//ur own piece of code
break;
}
}

Categories

Resources