When waiting for other threads to finish, we can use either join or CountdownLatch. What are the pros and cons of using either of those two mechanisms?
You can only use Thread.join if you're handling the threads yourself. Most people choose not to deal with the minutia of thread handling directly, and instead use an ExecutorService to handle it for them. ExecutorServices do not directly reveal how they are executing tasks, so you would have to use a CountDownLatch: (Assuming you don't want to just shutdown the whole service, that is.)
ExecutorService service = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(5);
for(int x = 0; x < 5; x++) {
service.submit(new Runnable() {
public void run() {
// do something
latch.countDown();
}
});
}
latch.await();
Another difference is after join(), thread can be unblocked only when joined thread has finished its execution while in CountDownLatch a thread can decrease the count anytime either on completion of thread or in between based on any condition.
This way we can get better control over unblocking of the thread instead of solely depending on the completion of joined thread.
join() is waiting for another thread to finish while CountDownLatch is designed for another purpose. If using CountDownLatch, You don't have to have reference of threads for which you are waiting as we have to do using join(). Let's assume you want to start a game when at least 2 players should be available. You can use countdownlatch in this case. But you can't achieve this using join easily because you don't have another thread(player in this case) on which you can write join().
A CountdownLatch is task-oriented - it's thread-agnostic. A whole pile of unrelated sets of tasks can be submitted to a threadPool and a CountdownLatch will ensure that each set notifies the originator of completion. Join() is an annoying abberation that links tasks to threads and, simply put, should never have entered the language in the first place. Sadly, a large, steaming pile of thread-tutorials mention Join() on the first page, thereby introducing threads to newbies as a deadlock-generator and generating thread-funk :(
CountdownLatchallows you to change the implementation of Item to maybe submit to an Executor service instead of using Threads directly.
The CountDownLatch class allows us to coordinate the starting and stopping of threads. Typical uses are as follows:
We can make several threads start at the same time;
We can wait for
several threads to finish (whereas, for example, the Thread.join()
method only lets you wait for a single thread).
You can have a look at this -> http://javahowto.blogspot.com/2011/08/when-to-join-threads-with.html
And this ->
A CountDownLatch's latch.await() method vs Thread.join()
Related
im an building a multithreaded application, using WorkerThreads which process Tasks from BlockingQueues. The worker looks as follws (as an abstract class. subclasses implement processItem()).
abstract class WorkerThread extends Thread {
BlockingQueue<Task> q;
int tasksInSystem; // globally available
public void run() {
while(!interrupted()) {
Task t = q.take();
process(t);
tasksInSystem--;
}
}
abstract void process(Task t);
}
The special thing is that i'd like to wait for all tasks to complete.
My first idea was to:
count each added task
decrease the counter when processing completed.
But:
But there are different types of Tasks and different worker implementations and multiple queues. So I would have to maintain tons of different counters.
What I'd like to have:
q.waitForEmptyAndCompleted()
That would require the queue to keep track of the Tasks "in flight" and require the Worker Processes to signal when they are done (instead of tasksInsystem---;).
The worker is not able to increase that counter, because he would have to count the tasks after he took them from the queue. But another thread may become running right after the take() call, such that the worker was not able to increase the counter beforehand.
Hence, the counter increase and take() must be tied together (atomar). Which leads me to a specialized BlockingQueue.
I didn't find a premade solution. So my best guess is to implement my own BlockingQueue. Is there something that I could use instead (to avoid implementing and testing a thread-safe blocking queue on my own)? Or do you have any idea to implement that wait call differently?
OK, since general ExecutorService is not enough perhaps ForkJoinPool will work, it does not expose queue explicitly, but should be very easy to use given what you have described.
Key method is awaitQuiescence(long timeout, TimeUnit unit) which will wait until all submitted tasks have finished execution.
After seaching a lot and not finding a concrete answer
If I have two threads started:
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t2.start();
After starting the threads I need the main thread to wait for these two thread to finish before printing the final result
How can I make the main thread wait for both t1 and t2?
A plain wait() would be enough?
Add
t1.join();
t2.join();
in your thread which should wait till t1 and t2 will finish their tasks (in your case call it from your main thread).
The answer depends...
You could
Use a CountDownLatch which is probably the simplest solution.
This way you would simply wait on the latch until it has been signaled the prescribed number of times (by each Thread terminating). This scales quite nicely as you increase the number of threads...
You could
Use join, but it would become tedious as you add more threads
You could
Add each Thread to a List, loop through the list, removing those threads that are no longer alive and keep looping until the List is empty, but that's a rather heavy handed approach.
You could
Combine the above solution with some kind of monitor lock which the loop would wait on and each Thread would notify when they complete, but it's not much cleaner and you could still end up waiting for non-existent threads...
You could
Use an ExecutorService and either use it's invokeAll and/or shutdown methods. See Executors for more details. This also scales quite nicely and even has the added benefit of allowing you to use a Thread pool to better manage the system resourcs
Check out the Thread#join method.
Also, you might find using an ExecutorService (and friends) helpful. Its essentially thread pool/management and provides a lot of conveniences and IMO a cleaner API than threads. Barrier to entry is low...
You want Thread#join(). wait() is for signalling, join() is to wait for the thread to finish.
Suppose there are three threads created using executor service and now I want that t2 would start running after t1 and t3 would start running after t2. how to achieve this kind of scenario in case of thread pool?
If it would have any normal thread creating using thread.start(). I could have waited using join() method. But how to handle above scenario?
Thread t1,t2 and t3 can implement callable interface and from the call method you can return some value.
Based on the return value, after t1 returns, you can initiate t2 and similarly for t3.
"Callable" is the answer for it
You are confusing the notion of threads and what is executed on a thread. It doesn't matter when a thread "starts" in a thread pool but when execution of your processing begins or continues. So the better statement is that you have 3 Callables or Runnables and you need one of the to wait for the other two before continuing. This is done using a CountDownLatch. Create a shared latch with a count of 2. 2 of the Callables will call countDown() on the latch, the one that should wait will call await() (possibly with a timeout).
Jobs submitted to an ExecutorService must be mutually independent. If you try to establish dependencies by waiting on Semaphores, CountDownLatches or similar, you run the risk of blocking the whole Service, when all available worker threads execute jobs that wait for a jobs that has been submitted, but is behind the current jobs in the queue. You want to make sure you have more workers than possible blocking jobs. In most cases, it is better to use more than one ExecutorService and submit each job of a dependent group to a different Service.
A few options:
If this is the only scenario you have to deal with (t1->t2->t3), don't use a thread pool. Run the three tasks sequentially.
Use some inter-thread notification mechanism (e.g. BlockingQueue, CountDownLatch). This requires your tasks to hold a shared reference to the synchronization instrument you choose.
Wrap any dependence sequence with a new runnable/callable to be submitted as a single task. This approach is simple, but won't deal correctly with non-linear dependency topologies.
Every task that depends on another task should submit the other task for execution, and wait for its completion. This is a generic approach for thread pools with dependencies, but it requires a careful tuning to avoid possible deadlocks (running tasks may wait for tasks which don't have an available thread to run on. See my response here for a simple solution).
I try to work with Java's FutureTask, Future, Runnable, Callable and ExecutorService types.
What is the best practice to compose those building blocks?
Given that I have multiple FutureTasks and and I want to execute them in sequence.
Ofcourse I could make another FutureTask which is submitting / waiting for result for each subtask in sequence, but I want to avoid blocking calls.
Another option would be to let those subtasks invoke a callback when they complete, and schedule the next task in the callback. But going that route, how to I create a proper outer FutureTask object which also handles exceptions in the subtask without producing that much of a boilerplate?
Do I miss something here?
Very important thing, though usually not described in tutorials:
Runnables to be executed on an ExecutorService should not block. This is because each blocking switches off a working thread, and if ExecutorService has limited number of working threads, there is a risk to fall into deadlock (thread starvation), and if ExecutorService has unlimited number of working threads, then there is a risk to run out of memory. Blocking operations in the tasks simply destroy all advantages of ExecutorService, so use blocking operations on usual threads only.
FutureTask.get() is blocking operation, so can be used on ordinary threads and not from an ExecutorService task. That is, it cannot serve as a building block, but only to deliver result of execution to the master thread.
Right approach to build execution from tasks is to start next task when all input data for the next task is ready, so that the task do not have to block waiting for input data. So you need a kind of a gate which stores intermediate results and starts new task when all arguments have arrived. Thus tasks do not bother explicitly to start other tasks. So a gate, which consists of input sockets for arguments and a Runnable to compute them, can be considered as a right building block for computations on ExcutorServices.
This approach is called dataflow or workflow (if gates cannot be created dynamically).
Actor frameworks like Akka use this approach but are limited in the fact that an actor is a gate with single input socket.
I have written a true dataflow library published at https://github.com/rfqu/df4j.
I tried to do something similar with a ScheduledFuture, trying to cause a delay before things were displayed to the user. This is what I come up with, simply use the same ScheduledFuture for all your 'delays'. The code was:
public static final ScheduledExecutorService scheduler = Executors
.newScheduledThreadPool(1);
public ScheduledFuture delay = null;
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something
}
}, 1000, TimeUnit.MILLISECONDS);
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something else
}
}, 2000, TimeUnit.MILLISECONDS);
Hope this helps
Andy
The usual approach is to:
Decide about ExecutorService (which type, how many threads).
Decide about the task queue (for how long it could be non-blocking).
If you have some external code that waits for the task result:
* Submit tasks as Callables (this is non blocking as long as you do not run out of the queue).
* Call get on the Future.
If you want some actions to be taken automatically after the task is finished:
You can submit as Callables or Runnables.
Just add that you need to do at the end as the last code inside the task. Use
Activity.runOnUIThread these final actions need to modify GUI.
Normally, you should not actively check when you can submit one more task or schedule callback in order just to submit them. The thread queue (blocking, if preferred) will handle this for you.
I'm faced with a very slow data import console app and I'm trying to speed it up by multithreading it.
Is there an example pattern for starting and managing X number of worker threads in a console app? Ideally I was hoping that there would be something like:
ThreadManager tm = new ThreadManager(maxthreads=10);
while (moreWork = true) {
tm.addThread(new Thread(new MyClass));
}
The ThreadManager would add threads until the max was reached and then wait patiently until a slot became available for a new thread.
Anything like that out there? I can't be the first one that's faced this problem.
#jeshurun's answer is correct but for posterity, I thought I'd add some more information. If you utilize the great ExecutorService code then your code would turn into:
ExecutorService threadPool = Executors.newFixedThreadPool(10);
while (moreWork) {
threadPool.submit(new MyClass);
}
// stop pool after you've submitted the last job, submitted jobs will still run
threadPool.shutdown();
// you can wait for the last job to finish if you'd like
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
Your MyClass should either implement Runnable or Callable. If it is a Runnable then the thread pool will execute the MyClass.run() method when it has an available thread. Same with Callable except that the Future<?> returned by the submit() method can be used to get the value returned by your MyClass.call() method. You can also get any exceptions that were thrown by call(). Here's a decent tutorial.
If you are using Java 5 or above, why don't you use the ExecutorService interface from the java.util.concurrent framework, and its implementation ThreadPoolExecutor for managing a fixed number of threads? Normally you would use one of the static methods in the Executors class to obtain an instance of a ThreadPool with a fixed size, and submit as many threads as you want to it for execution.
The documentation for ThreadPoolExecutor and all its friends in the java.util.concurrent package is available here.