I am having a class that is accessed by multiple threads, each thread request one method of this class. Each method in turn performs number of Callables. This class uses threadPool from ExecutorService to execute these Callables through invokeAll((Collection>) executableTasks) method.
The setup looks like this:
public MyClass {
private final ExecutorService threadPool = Runtime.getRuntime().availableProcessors();
public void method1() {
List<SomeObject> results = new ArrayList<>();
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
tasks.add(new Callable<Void>(){ ... results.add(someObject);} );
threadPool.invokeAll(tasks);
}
public void method2() {
List<SomeObject> results = new ArrayList<>();
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
tasks.add(new Callable<Void>(){ ... results.add(someObject);} );
threadPool.invokeAll(tasks);
}
}
I am confused if this will execute tasks in class concurrently or invokeAll() will block execution till tasks in one method completes(means execution will happen concurrently inside methods but not at class level)? Or Should I use CompletionService to find out the corresponding results of tasks?
ExecutorService#invokeAll executes all the tasks concurrently, but the call itself blocks until all the tasks complete.
For example, let's say you have three tasks that take 6 sec, 2 sec, and 10 sec to complete. If you were to execute these synchronously, it would take at least 6 + 2 + 10 = 18 seconds. However, using invokeAll (on a sufficiently large thread pool), this could take as little as the longest time, or 10 seconds.
This means that the methods method1() and method2() are both blocking methods because of the use of invokeAll(). When you call method1(), it will block until all of the requests added into the list of callables are complete. Same goes for method2(). If these methods are called from different threads, then the tasks in both methods will execute concurrently.
If you want the methods to be asynchronous, you'll want to call threadPool.submit(callable) individually for each task inside the methods and collect the returned futures in a list. You could either return a List or use a CompletionService to help for this, yes.
PS - this line in your example won't work:
ExecutorService threadPool = Runtime.getRuntime().availableProcessors();
I think you want this instead:
ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Hope this helps.
To me, this will execute tasks in class concurrently. invokeAll() waits until all its tasks are finished but that is for the current thread, while this thread is waiting, other thread can execute its tasks concurrently
According to the Java Specification invokeAll execute all tasks concurrently independently of one another. and repeated calls to invokeAll will do the same, That is, the call to invokeAll not block the execution of tasks.
Visit:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/AbstractExecutorService.html
Related
I currently have a bunch of tasks that I want to execute. I am using the single-threaded executor in java. These are mainly of 2 types. Let's call these types TaskA and TaskB. I have 10 tasks of type TaskA and 5 tasks of type TaskB. I have to execute them all but I cannot control the sequence in which they are submitted to the executor. A few tasks of type TaskB might be submitted to the executor before all 10 tasks of type TaskA have been submitted. Is there any way to ensure that all 10 tasks of type TaskA are executed before the 5 tasks of type TaskB? In order to successfully execute all tasks of type TaskB, I need to first execute all tasks of type TaskA. You may think of TaskA tasks to be responsible for data loading and TaskB tasks for data processing. Without loading the data I cannot process it and run into exceptions
Please do let me know if I can phrase the question better if it is unclear
No, the default executor service implementations do not differentiate between submitted tasks.
You need a task manager object.
Define a class that contains the single-threaded executor service as a member field. That class offers methods submit( TaskA ta ) and submit( TaskB tb ).
The second method collects the B tasks, as a queue, holding them for now if we’ve not yet processed ten A tasks.
The first method accepts each A task, submitting to the executor service immediately. And the first method counts those submissions. On the tenth A task, flag is set, and all stored B tasks are submitted to the member field executor service.
The second method always checks for that “A tasks done” flag being set. If set, any further B tasks submissions are sent directly to the executor service.
Your task manager class could itself implement the ExecutorService interface. But I don’t know if I would go that far.
The way I think you could do this is using the semaphore/locking pattern.
first, you need a lock. You can use an object
Object lock = new Object();
Then you need a count of how many A tasks have completed.
int completedAs = 0; // variable name is completed 'A's, not 'as'
Both of these should be static or otherwise available to TaskA and TaskB. Then what you can do is only add the TaskB's to the ExecutorService when the appropriate number of TaskA's have completed, like
for (TaskB : allTaskBs) {
synchronized(lock) {
//add the taskB to the ExecutorService
}
}
And then upon taskA completion:
synchronized(lock) {
completedAs++;
if (...) {
lock.notify(); // you can call this multiple times to release multiple B's
}
}
Here is something of a weird solution. Provided you have a default executor.
ExecutorService service = Executors.newSingleThreadExecutor();
Your need to keep track of how many a tasks have completed and how many need to be completed.
AtomicInteger a = new AtomicInteger(0);
int totalA = 10;
Then for submitting a task.
void submitTask(Runnable t){
Runnable r = ()->{
if( t instance of TaskA ){
try{
t.run();
} finally{
a.incrementAndGet();
}
} else if( t instance of TaskB ){
if( a.get() >= totalA ){
t.run();
} else{
service.submit(this);
}
} else{
throw new RuntimeException("not an acceptable task!");
}
}
service.submit(r);
}
This will filter the TaskA's and the TaskB's, TaskA's will be immediately executed, but TaskB's will be resubmitted.
There are some flaws to this design. I think ThreadPoolExecutor can be setup a little better where you reject a task if it is not ready to be run.
I suspect that you could design your setup a little better. They have tools like an ExecutionCompletionService, or CountDownLatch that are made for creating barriers to execution.
I am having confusion with defining executor in CompletableFuture. I am not sure how to tell CompletableFuture to run it in that particular executor. Thanks in advance.
//Suppose I have an executor
ExecutorService myExecutor=Executors.newFixedThreadPool(2);
//If I create a future like this
CompletableFuture.runAsync(() -> {
//Do something
}, myExecutor); // I can put the executor here and say the future to this executor
//But I do not know where to put executor if I create my future in method style like this
private final CompletableFuture<Void> myMethod(String something) {
//Do something
return null;
}
//and use it like this
.thenCompose(this::myMethod); //How can I specify the executor in this case?
In your example, you have 3 CompletableFutures that are at play:
the one returned by runAsync()
the one returned by myMethod()
the one returned by thenCompose()
You also have 4 tasks that need to be run:
the one passed to runAsync() will be executed on the given executor and handle future 1;
the one that calls myMethod() from thenCompose() to create future 2 can be run on any executor, use thenComposeAsync() to explicitly choose one;
the one that will complete future 2 returned by myMethod() – this will be controlled inside myMethod() itself;
the one that will complete future 3 returned by thenCompose() – this is handled internally and will depend on execution order (e.g. if myMethod() returns an already completed future, it will also complete the former).
As you can see, several tasks and executors are involved, but you can always control the executors used in dependent stages using *Async() variants. The only case where you don't really control it is the 4th case, but it is a cheap operation as long as dependent stages use the *Async() variants as well.
you can do something like this:
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();
I have a list of objects, from which depending on user interaction some objects need to do work asynchronically. Something like this:
for(TheObject o : this.listOfObjects) {
o.doWork();
}
The class TheObject implements an ExecutorService (SingleThread!), which is used to do the work. Every object of type TheObject instantiates an ExecutorService. I don't want to make lasagna code. I don't have enough Objects at the same time, to make an extra extraction layer with thread pooling needed.
I want to cite the Java Documentation about CachedThreadPools:
Threads that have not been used for sixty seconds are terminated and
removed from the cache. Thus, a pool that remains idle for long enough
will not consume any resources.
First question: Is this also true for a SingleThreadExecutor? Does the thread get terminated? JavaDoc doesn't say anything about SingleThreadExecutor. It wouldn't even matter in this application, as I have an amount of objects I can count on one hand. Just curiosity.
Furthermore the doWork() method of TheObject needs to call the ExecutorService#.submit() method to do the work async. Is it possible (I bet it is) to call the doWork() method implicitly? Is this a viable way of designing an async method?
void doWork() {
if(!isRunningAsync) {
myExecutor.submit(doWork());
} else {
// Do Work...
}
}
First question: Is this also true for a SingleThreadExecutor? Does the thread get terminated?
Take a look at the source code of Executors, comparing the implementations of newCachedThreadPool and newSingleThreadExecutor:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
The primary difference (of interest here) is the 60L, TimeUnit.SECONDS and 0L, TimeUnit.MILLISECONDS.
Effectively (but not actually), these parameters are passed to ThreadPoolExecutor.setKeepAliveTime. Looking at the Javadoc of that method:
A time value of zero will cause excess threads to terminate immediately after executing tasks.
where "excess threads" actually refers to "threads in excess of the core pool size".
The cached thread pool is created with zero core threads, and an (effectively) unlimited number of non-core threads; as such, any of its threads can be terminated after the keep alive time.
The single thread executor is created with 1 core thread and zero non-core threads; as such, there are no threads which can be terminated after the keep alive time: its one core thread remains active until you shut down the entire ThreadPoolExecutor.
(Thanks to #GPI for pointing out that I was wrong in my interpretation before).
First question:
Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources.
Is this also true for a SingleThreadExecutor?
SingleThreadExecutor works differently. It don't have time-out concept due to the values configured during creation.
Termination of SingleThread is possible. But it guarantees that always one Thread exists to handle tasks from task queue.
From newSingleThreadExecutor documentation:
public static ExecutorService newSingleThreadExecutor()
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
Second question:
Furthermore the doWork() method of TheObject needs to call the ExecutorService#.submit() method to do the work async
for(TheObject o : this.listOfObjects) {
o.doWork();
}
can be changed to
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
with Callable or Runnable interface and add your doWork() code in run() method or call() method. The task will be executed concurrently.
I'm trying to write a process in Java that executes a series of tasks concurrently, waits for the tasks to be done, then tags the overall process as complete. Each task has its own information, including when the individual task is complete. I'm using an ExecutorService for the process, and have boiled down the essence of the process as follows:
List<Foo> foos = getFoos();
ExecutorService executorService = Executors.newFixedThreadPool(foos.size());
for (Foo foo : foos) {
executorService.execute(new MyRunnable(foo));
}
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// log the error.
}
completeThisProcess();
Each of the MyRunnable objects has a run method that makes a webservice call, then writes the results of the call to the database, including the time the call completed. The completeThisProcess method simply writes the status of the whole process as complete along with the time the process completed.
The problem I'm having is that when I look in the database after the process has completed, the completeThisProcess method has apparently been able to execute before all of the MyRunnables have completed. I'm noticing that the times that are written from the completeThisProcess method are even occasionally upwards of 20-30 seconds before the last MyRunnable task has completed.
Is there anything there that is obviously wrong with the process I've written? Perhaps I'm not understanding the ExecutorService correctly, but I thought that the awaitTermination method should be ensuring that all of the MyRunnable instances have completed their run methods (assuming they complete without exception, of course), which would result in all the sub-tasks having completion times before the overall process's completion time.
If you want to wait for all the threads to return is then following method can be trusted.
Make your thread class implement Callable interface instead of Runnable (In case of Callable run method will return some value. Make it return threadName.
Create a list of Callable Objects and use invokeAll method which will wait for all threads to return. For the below code assume the thread class name to be MyCallable.
ExecutorService executorService = Executors.newFixedThreadPool(foos.size());
List<Callable> tasks = new ArrayList<>();
for (Foo foo : foos) {
tasks.add(new MyCallable(foo));
}
executorService.invokeAll(tasks);
invokeAll returns List of future objects if you want to make use of it.
OR
you can use CountDownLatch.
CountDownLatch cdl = new CountDownLatch(foo.size);
Make it count down in run method using cdl.countDown() method.
Use cdl.await after for loop and then it will wait untill cdl become zero.
Heading
Alright, i'll explain what i am asking by giving an exemple.
lets say im trying to implement a parallel merging algorithm when given:
db is an array where db[i] is an ArrayList of objects.
j is its size.
Merger(db,cmp,i,j) is a runnable that merges db[ j ] into db[i].
cmp is a relevant Comparator.
This is what i have Firstly Done:
ExecutorService e = Executors.newFixedThreadPool(3);
while (j>0)
for ( i=0;i<j;i++,j--)
e.execute(new Merger<E>(db,cmp,i,j));
but then some merges were started while previous merges that needed to be finished first were not yet finished. (not to mention that the running thread finished the loop way before the merging was finished...) and that made my program kick out an Exeception.
This is what I CANT DO, but WANT TO DO, and therefore need your help:
ExecutorService e = Executors.newFixedThreadPool(3);
while (j>0) {
for ( i=0;i<j;i++,j--)
e.execute(new Merger<E>(db,cmp,i,j));
wait for e to announce that all runnables have finished running;
}
in my opinion this should work, if you think not then explain why, but anyway, i want to know how its done.
(basicly i can implement my own version of FixedThreadPool to make it heppen but i rather not)
You might be looking for a CountDownLatch:
Determine the number of threads you need to wait for and create a CountDownLatch with that number
Pass the latch to all worker threads when constructing them and have them call countDown() once they finish.
After the loop that enqueues worker threads, await() that the countdown reaches zero.
You need a 'startAndRendezvous' runnable that issues merges and waits for them to complete. Usually, this is done by creating a set of merge runnable tasks set with a callback pointing to a CountDownlatch in the startAndRendezvous or, more flexibly, pass the startAndRendezvous as a constructor parameter to the merge runnables.
Latest Java has a ForkJoinPool. Look at the class - it saves having an explicit countdown latch.
An easy way that should work is to define a static counter in Merger:
public class Merger<E> ... {
public static int runningCount=0;
public Merger(...){
runningCount++;
}
public void run(){
...
runnningCount--;
}
}
Then :
ExecutorService e = Executors.newFixedThreadPool(3);
while (j>0) {
for ( i=0;i<j;i++,j--)
e.execute(new Merger<E>(db,cmp,i,j));
while(Merger.runningCount>0)
Thread.sleep(10);
}