I have a requirement in multi-threaded environment in java. The problem is like;
I have suppose 10 different task, and I want to assign all these 10 task to 10 different threads. Now the finish time for these tasks could be different. And there is some finishing or clearance task which should be performed when all these 10 threads are finished. In other words i need to wait until all threads are finished and then only I can go ahead with my further code execution.
Please let me know if any more details required here.
Thansk,
Ashish
Sounds like an ideal job for CountDownLatch.
Initialize it with 10 counts and when each thread finishes its job, it counts down one.
When all 10 threads have finished, the CountDownLatch will let the original thread run, and it can perform the cleanup.
And fire up an ExecutorService with 10 fixed threads to run the tasks.
CyclicBarier (JDK java.util.concurrent) of size 10 is perfect solutuon for you. With CyclicBarier you can wait for 10 threads. If all t hreads achieve barier then you can go further.
Edit: CyclicBarier is almost the same as CountDownLatch but you can reuse barier invoking reset() method.
Whilst CountDownLatch and CyclicBarier do the job of synchronizing multiple threads and performing one action when all threads reach the required point, they require all tasks to actively use this feature. If you are interested in the finishing of the entire task(s) only, the solution can be much simpler: add all tasks to a Collection and use the invokeAll method of an ExecutorService which returns when all tasks have been completed. A simple example:
Callable<Void> simpleTask=new Callable<Void>() {
public Void call() {
System.out.println("Performing one job");
return null;
}
};
List<Callable<Void>> list = Collections.nCopies(10, simpleTask);
ExecutorService es=Executors.newFixedThreadPool(10);
es.invokeAll(list);
System.out.println("All completed");
If each thread terminates after it is finished, you could just use the join() statement. A simple example can be found in the Essential Java Tutorials.
ArrayList<Thread> myThreads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++){
//MyTaskRunnable is a Runnable with your logic
Thread t = new Thread(new MyTaskRunnable());
myThreads.add(t);
}
for(Thread t : myThreads){
t.start();
}
//here all threads are running
for(Thread t : myThreads){
t.join();
}
//here all threads have terminated
Edit:
The other answers all have their merits and are very useful in practice, the join() is however the most basic of the constructs. The CyclicBarrier and CountDownLatch versions allow your threads to continue running after reaching the synchronization point, which can be necessary in some cases. The ExecutorService is more suited to many tasks needing to be executed on a fixed number of threads (aka a thread pool), to create an ExecutorService for just 10 tasks is a bit drastic.
Finally, if you are new to learning Java or are taking a course on concurrency, you should try out all the variants and see what they do. The join is the most basic of these constructs and will help you understand you what is going on. Also it is the basic model supported by most other languages.
Related
I have the following piece of code, I have a large loop that I want to run in parallel. Unfortunately a race condition exists, in some cases (not all, not predictable) I get blocked at s.awaitTermination. There is no thread synchronization except at the end where I remove the finished thread from the set, and if the set is empty call shutdown. Where am I going wrong? FYI thousands of tasks get added to the queue, I don't want them all trying to run at once, is there a better pattern than this?
When I check the queue, it has tasks left, and the pool threads are "parked at unsafe...." according to Netbeans debug.
EDIT: updating Thread to Runnable as suggested - did not fix the problem
ExecutorService s = Executors.newFixedThreadPool(8);
final Set<Runnable> threads = new HashSet<>();
for(/*lots of loops*/){
Runnable t = new Runnable(){
public void run(){
//some long task...
synchronized(threads){
threads.remove(this);
if(threads.isEmpty()){
s.shutdown();
}
}
}
}
}
synchronized(threads){
for(Runnable t : threads){
s.submit(t);
}
}
s.awaitTermination(1000, TimeUnit.SECONDS);
This is not is a solution for your question, but it might help you to do the same task easily. Take a look at the ExecutorCompletionService it can execute multiple tasks and it will return you a future that you can use to wait. Internally it uses a queue for the completed tasks so basically accomplished what you are trying to do here.
The Java ExecutorService framework allows you to delegate a number of tasks to be performed using a managed thread pool so that N tasks can be performed X tasks at a time until complete.
My question is ... what if N is a number that is either infinite or so large as to be impractical to allocate/assign/define initially.
How can you leverage the concept of thread pooling in Java (ExecutorService) to handle more tasks than you could reasonably submit without exhausting resources.
For purposes of this answer, assume each task is self-contained and does not depend on any other task and that tasks can be completed in arbitrary order.
My initial attempt at attacking this problem involved feeding the ExecutorService Y threads at a time but I quickly realized that there's no apparent way to tell when a particular task is complete and therefore submit a new task to be executed.
I know I could write my own "ExecutorService" but I am trying to leverage the bounty of what the Java framework already provides. I'm generally in the "don't re-invent the wheel" category because greater minds than mine have already made investments for me.
Thanks in advance to anybody that can provide any insight in how to attack this type of problem.
You could use a CompletionService to do it. You can have one thread that seeds the service with a bunch of tasks, then as tasks complete you can add new ones.
A simple example:
final CompletionService service = new ExecutorCompletionService(Executors.newFixedThreadPool(5));
Runnable taskGenerator = new Runnable() {
public void run() {
// Seed the service
for (int i = 0; i < 100; ++i) {
service.submit(createNewTask());
}
// As tasks complete create new ones
while (true) {
Future<Something> result = service.take();
processResult(result.get());
service.submit(createNewTask());
}
}
};
new Thread(taskGenerator).start();
This uses a ThreadPoolExecutor with 5 threads to process tasks and a hand-rolled producer/consumer thread for generating tasks and processing results.
Obviously you'll want something a little smarter than while (true), you'll need to have sensible implementations of processResult and createNewTask, and this assumes that task execution is much slower than generating them or processing the results.
Hopefully this will get you on the right track.
Use java.util.concurrent.ThreadPoolExecutor with java.util.concurrent.ArrayBlockingQueue as its workQueue. This way attempt to put more tasks than the size of the queue would block.
BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor tpe=new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, workQueue);
while (true) {
tpe.execute(createNewTask());
}
I'm implementing a parallel, performance-critical algorithm with multiple threads. I assign all threads some data to work on. When all those threads have finished to work on their data, I assign all threads new data, and the cycle continues. (This is what I refer to as thread "clocking" since it's somewhat similar to CPU clocking.)
What I came up with so far is using a master thread that stores an integer. At the beginning of each cycle, I set the integer to the number of slave threads. When a slave thread is done, it decrements the master thread's integer. Once that integer reaches zero, I start a new cycle.
Is this a good approach, or are there more efficient ways of doing the same thing?
You'd be better off using a Phaser (if you have Java 7), or CyclicBarrier for Java 5+.
I would recommend looking at the newer classes in the java.util.concurrent package, especially ThreadPoolTaskExecutor. You might be reinventing the wheel if you haven't looked beyond java.lang.Thread.
Well. See CyclicBarrier (JavaDoc)
A better way is to use Thread.join(). In you main thread, you call join() on all the threads you are starting. The main thread will wait untill all joined threads are finished.
See for example http://javahowto.blogspot.com/2007/05/when-to-join-threads.html
An ExecutorService can do this for you.
ExecutorService executor = Executors.newFixedThreadPool(10);
do {
List<Callable> tasks = getNextTasksToExecute();
executor.invokeAll(tasks);
} while (tasks.size() > 0);
This will create a thread pool with 10 threads. It will then call getNextTasksToExecute() which you should implement yourself to return the next bunch of tasks that need doing. It will execute those tasks in parallel in the thread pool and then keep looping until getNextTasksToExecute() returns no more tasks.
Edit:
Code not tested, think there may be a compile error, but you can figure that out.
I was trying to run ExecutorService object with FixedThreadPool and I ran into problems.
I expected the program to run in nanoseconds but it was hung. I found that I need to use Semaphore along with it so that the items in the queue do not get added up.
Is there any way I can come to know that all the threads of the pool are used.
Basic code ...
static ExecutorService pool = Executors.newFixedThreadPool(4);
static Semaphore permits = new Semaphore(4);
try {
permits.acquire();
pool.execute(p); // Assuming p is runnable on large number of objects
permits.release();
} catch ( InterruptedException ex ) {
}
This code gets hanged and I really don't know why. How to know if pool is currently waiting for all the threads to finish?
By default, if you submit more than 4 tasks to your pool then the extra tasks will be queued until a thread becomes available.
The blog you referenced in your comment uses the semaphore to limit the amount of work that can be queued at once, which won't be a problem for you until you have many thousands of tasks queued up and they start eating into the available memory. There's an easier way to do this, anyway - construct a ThreadPoolExecutor with a bounded queue.* But this isn't your problem.
If you want to know when a task completes, notice that ExecutorService.submit() returns a Future object which can be used to wait for the task's completion:
Future<?> f = pool.execute(p);
f.get();
System.out.println("task complete");
If you have several tasks and want to wait for all of them to complete, either store each Future in a list and then call get() on each in turn, or investigate ExecutorService.invokeAll() (which essentially does the same but in a single method call).
You can also tell whether a task has completed or not:
Future<?> f = pool.execute(p);
while(!f.isDone()) {
// do something else, task not complete
}
f.get();
Finally, note that even if your tasks are complete, your program may not exit (and thus appears to "hang") if you haven't called shutdown() on the thread pool; the reason is that the threads are still running, waiting to be given more work to do.
*Edit: sorry, I just re-read my answer and realised this part is incorrect - ThreadPoolExecutor offers tasks to the queue and rejects them if they aren't accepted, so a bounded queue has different semantics to the semaphore approach.
You do not need the Semaphore.
If you are hanging it is probably because the threads are locking themselves elsewhere.
Run the code in a Debuger and when it hangs pause it and see what the threads are doing.
You could change to using a ThreadPoolExecutor. It contains a getActiveCount() method which returns an approximate count of the active threads. Why it is approximate I'm not sure.
I saw a stackoverflow member suggest using Thread.join() to have a "main" thread wait for 2 "task" threads to complete.
I will frequently do something different (shown below) and I want to know if there are any problems with my approach.
final CountDownLatch latch = new CountDownLatch(myItems.length);
for (Item item : myItems) {
//doStuff launches a Thread that calls latch.countDown() as it's final act
item.doStuff(latch);
}
latch.await(); //ignoring Exceptions for readability
Your solution is easier to scale. Thread.join() was a perfectly fine way of resolving your issue before CountdownLatch and the other synchronizers were created.
In terms of readability, I would choose the CountdownLatch approach over joining on each thread. This also allows you to change the implementation of Item to maybe submit to an Executor service instead of using Threads directly.
I would prefer using a Future (easy if you're using an ExecutorService). Then after submitting all the tasks wait for them all to finish.
Collection<Future<Void>> futures = new ArrayList<Future<Void>>(myItems.length());
for ( Runnable item : myItems ) {
futures.add(executor.submit(item, null));
for ( Future<Void> future : futures )
future.get(); //easy to add a timeout here
The final for-loop could easily be separated into a utily method. This encapsulates the synchronization and makes it easy to add timeouts.
It's also more applicable to the general case, where the worker threads actually need to return a result. (If you don't care about what the worker threads end up doing, why do you need to wait for them?)
The countdown latch is preferred for simultaneously starting all the threads at the same time.