Having -
for (int i = 0; i<10 ; i++) {
Runnable r = new Runnable(){...}
new Thread(r).start();
}
// I want to continue here only after all the subclass threads before exited .
...
How could I make sure all the subclass threads exited before I continue on after the for section ?
Does exist any solution besides keep all the Runnable's in a List<Runnable> and finally check its isAlive() for each element ?
How could I make sure all the subclass threads exited before I continue on after the for section ?
I'd use the ExecutorService classes. See the Java tutorial on them. Something like:
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
threadPool.submit(new Runnable(){...});
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
Then you can wait for them to finish with:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
If you still want to do your own threads then typically you keep them around in a List and call join() on each one of them:
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new Runnable(){...});
thread.start();
threadList.add(thread);
}
// this waits for all of the threads to finish before continuing
for (Thread thread : threadList) {
thread.join();
}
Have a look at CountDownLatch. It is great for when you want to wait for N threads to be done with something.
Related
After Starting the thread object
thread1.start();
thread2.start();
i need to wait for the finalization of both threads using the join() method(the most common way).
Like this.
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
All the tutorial i see uses some inbuilt method for finalization of threads.
Is there a way to wait for thread finalization without using any inbuilt method like join or executor ?
Every Thread has a state. NEW , RUNNABLE , BLOCKED , WAITING , TIMED_WAITING , or
TERMINATED
TERMINATED is a state that you can look for every thread with thread.getState() method, which is the state of thread once it finish execution
// 2 Thread Object
Thread threads[] = new Thread[2];
// store Thread Statuses
Thread.State status[] = new Thread.State[2];
Since All Thread have state. Before starting thread store
their state
for (int i = 0; i < 2; i++) {
status[i] = threads[i].getState();
}
Once you start the thread
The finished Thread has a state of Terminated, you can use it to
and write your own check for finalization
// custom way for finalization of the threads
boolean finish = false; // initially all non finised
while(!finish) {
for (int i = 0; i < 2; i++) {
if (threads[i].getState() != status[i]) {
status[i] = threads[i].getState();
}
}
finish = true;
for (int i = 0; i < 2; i++) {
finish = finish && (threads[i].getState() ==
State.TERMINATED);
}
}
I have four threads running and I want to throw a flag when they're all done. What I want to do is have an int set to 0. When a thread finishes it'll add 1 to that int. I'll have an if statement at the end that'll have the condition that the int has to equal 4. When that happens a message will show up indicating that all the threads are done. However, when I try to do this it says ints have to be final or effectively final. How do I get around this?
The easiest way is just to use Thread.join():
Thread[] ts = new Thread[4];
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(...);
ts[i].start();
}
for (int i = 0; i < ts.length; ++i) {
ts[i].join(); // Wait for the i-th thread to die.
}
Amongst other alternatives, you can use a CountdownLatch, which gives you a little bit more flexibility as to when the thread is considered "finished":
Thread[] ts = new Thread[4];
final CountdownLatch latch = new CountdownLatch(ts.length);
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(new Runnable() {
#Override public void run() {
// ...
latch.countDown();
}
});
ts[i].start();
}
latch.await(); // Blocks until all threads have called `countDown()`.
There are many ways you can do that. If you want your main thread to be blocked while your other 4 threads are running, you can do
t1.join();
t2.join();
t3.join();
t4.join();
And this way your main thread will wait for the execution of all the other threads. If you want each thread to increment your flag, you can pass it in their constructors, but you should make the flag AtomicInteger
Another way to solve this is to use ThreadPool. You can make a ThreadPool of four threads and assign four Runnable tasks to them. Then you can invoke the .submit(Runnable) method to the threads. This way the 4 threds would execute the four tasks.
The .submit() method of the ExecutorService (which is the object that operates with the 4 threads) returns a so-called Future object. When invoking future.get() you will know that the thread has finished its task:
ExecutorService executor = Executors.newFixedThreadPool(4);
ArrayList<Runnable> tasks = new ArrayList<>();
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
ArrayList<Future> results = new ArrayList<>();
for(Runnable t : tasks){
results.add(executor.submit(t));
}
int myIntFlag = 0;
for(Future f : results){
f.get();
myIntFlag++;
System.out.println("Part" + myIntFlag + " of the job is ready")
}
System.out.println("Whole Job ready")
There are multiple ways you can achieve the same. Use any of them:
(a) Use Atomic Integer as flag and increase the flag count
(b) use CountdownLatch
(c) you can also tune cyclicbarrier for that (barrier at the end of each thread).
(d) use Thead.join()
~ Java Guru:
Blogger at Java Interview Questions and Answers
If you really want an int counter variable, you could either mark it as volatile or use an AtomicInteger.
volatile int counter = 0;
or
final AtomicInteger counter = new AtomicInteger();
Keep in mind that you'll have to loop polling this variable in your main thread until it is 4. If for some reason one of the threads don't get to increment it, your main thread will hang forever.
In my main flow I have a thread pool ExecutorService, i fill it with a "known" number of Callables, that I invokeAll().
Also there is another ExecutorService object called "globalPool" (my assamption that ExecutorService is thread-safe and I can add tasks to it from different threads ).
Now, each of above Callables spawns new tasks and put them (submit) to this shared "globalPool".
The problem is that I can't know (can't block) when all tasks are completed and if there are no more incoming tasks.
Please assist.
Code snippet:
public class Worker implements Callable {
private ExecutorService sharedPool;
public Worker (ExecutorService pool){
this.sharedPool = pool;
}
public boolean call() {
for (int i = 0; i<100; i++){
if(i % 10 == 0){
sharedPool.submit(new Runnable() {
public void run() {
heavyTaskHere();
}
}
}
}
}
}
Main flow:
ExecutorService sharedPool = new Executors.newFixedThreadPool(X);
List<Callable<Boolean>> mainthareadPool= new ArrayList<Callable<Boolean>>();
ExecutorService executor = Executors.newFixedThreadPool(N);
for (int i = 0; i<10; i++){
Wroker w = new Worker (sharedPool);
mainthareadPool.add(w);
}
executor.invokeAll(mainthareadPool);
As I see it The Callables will end before their Runable will end.
If you invokeAll your Callables you get back a List of Futures corresponding to your Callables . With that Futures you can simply see if the Callables has completed by yourFutureList.get(futureOfInterestIndex).isDone()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to know if other threads have finished?
I have a threadpool that executes threads for me, how can I tell when ALL the threads I've passed it are done?
For example:
main.java
for (int i = 0; i < objectArray.length; i++) {
threadPool.submit(new ThreadHandler(objectArray[i], i));
Thread.sleep(500);
}
ThreadHandler.java
public class ThreadHandler implements Runnable {
protected SuperHandler HandlerSH;
protected int threadNum;
public ThreadHandler(SuperHandler superH, int threadNum) {
this.threadNum = threadNum;
this.HandlerSH = superH;
}
public void run() {
//do all methods here
}
Would I just put something into the run() section to set a boolean or something? Would I make an array of boolean to check when they're all done?
Thanks.
When you submit a job into a thread pool, it returns a Future instance. You can call Future.get() to see if the job has finished. This is effectively similar to a join on the tasks running in a thread pool.
You can also call threadPool.awaitTermination(...) if the thread-pool has been shutdown and you want to wait for all of the tasks have finished.
Often when I am submitting a number of jobs into a thread pool, I record their futures in a list:
List<Future<?>> futures = new ArrayList<Future<?>>();
for (int i = 0; i < objectArray.length; i++) {
futures.add(threadPool.submit(new ThreadHandler(objectArray[i], i)));
}
// if we are done submitting, we shutdown
threadPool.shutdown();
// now we can get from the future list or awaitTermination
for (Future<?> future : futures) {
// this throws an exception if your job threw an exception
future.get();
}
I have one main thread that starts 10 other threads. I want that the main thread will be finished only after all other threads stopped. So should I call join() on other 10 threads before starting or after starting them. For instance:
// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
// ParserThread() is a runnable thread
threads[i] = new Thread(new ParserThread());
threads[i].join();
threads[i].start();
}
System.out.println("All threads have been finished"); // line no. 9
So as in the above example, should i call join() before start() or after start().
Will the control returns to line no. 9 only after all the threads have finished.
When the run method of any thread has been executed, then will that thread die or remain alive. If it will, the how to die all the threads when their run method has finished means when the control returns to line no. 9
Calling join() on a thread only makes sense after the thread is started. The caller of join() will stop and wait until the other thread finishes what it's doing. So you may want to do this:
// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
// ParserThread() is a runnable thread
threads[i] = new Thread(new ParserThread());
threads[i].start();
}
System.out.println("All threads have been started");
for(int i = 0; i < 10; i++) {
threads[i].join();
}
System.out.println("All threads have been finished");
I recommend against using the low-level Thread constructs like join(), and instead using the higher-level stuff in java.util.concurrent, like CyclicBarrier:
A synchronization aid that allows a
set of threads to all wait for each
other to reach a common barrier point.
CyclicBarriers are useful in programs
involving a fixed sized party of
threads that must occasionally wait
for each other. The barrier is called
cyclic because it can be re-used after
the waiting threads are released.
The usage is much more obvious that Thread.join(), and much less prone to weird bugs.
Instead of writing your own code, you code use a ThreadPoolExecutor to do what you need:
ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 10, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 10; i++)
executor.execute(new ParserThread());
try {
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (final InterruptedException e) {
// handle
}
This way, you could easily use less threads to do more tasks if you wish - without changing the code.
you should first start all the thread, then start joining them. Join will return direct if called before the thread is start.
Case can be that you want to join group of threads. See javadoc for
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
void solve(Executor e,
Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException {
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
For trivial scenarios (one thread), Thread.join() is enough.