How to join one thread with other in java? - java

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.

Related

Custom Way to Wait for all thread to complete in Java?

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);
}
}

BlockingQueue program does not exit

I was referring the concept of BlockingQue and I found one example here.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /* j a v a 2s . co m*/
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue < Integer > queue = new ArrayBlockingQueue < Integer > (capacity);
int numWorkers = 2;
Worker[] workers = new Worker[numWorkers];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Worker(queue);
workers[i].start();
}
for (int i = 0; i < 10; i++) {
queue.put(i);
}
}
}
class Worker extends Thread {
BlockingQueue < Integer > q;
Worker(BlockingQueue < Integer > q) {
this.q = q;
}
public void run() {
try {
while (true) {
Integer x = q.take();
if (x == null) {
break;
}
System.out.println(x);
}
} catch (InterruptedException e) {}
}
}
In the example, they have used only one thread which is a Worker thread.
What I understood about BlockingQue is that it is an alternate solution to Producer-Consumer pattern.
So we need two threads to work on. Hence I have doubts/questions.
Below are my questions.
have they used main thread as another thread?
When I run the application, the program does not get exited. I did not understand the reason why the main program does not exit?
In the example code that you are referring , you have one Producer (Main Thread) and two Consumers (Worker Threads).
In Producer - Consumer problem, its not necessary to have only one Producer and only one Consumer - you can have multiple producers and multiple consumers. Their relative number is usually decided about who is doing more complex and time consuming tasks.
Answer 1: main thread is producer thread since it is being used to put items to BlockingQueue, queue.put(i)
Answer 2: your main thread exits after putting ten elements to queue but your worker thread keeps waiting for elements ( even after consuming ten elements ) because q.take() is a blocking method i.e. it waits for more elements to be put to queue (when queue is empty)
Solution : You need to put two EOF elements / Objects (END OF FILE) to queue and do a check like you did , if (x == null). Try putting two extra nulls in queue so when your worker/consumer threads find it, they will terminate. Currently, your condition if (x == null) is never met.
Answer 1. No they have not used main thread for anything else. Main thread exit perfectly.
Answer 2. JVM does not exit until all the non-daemon thread ends. (Source: http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html)
If you want the JVM to exit once the main thread finishes make your Worker threads to daemon thread by adding workers[i].setDaemon(true); inside your for loop.
The reason why your non-daemon threads doesn't exist is you have Integer x = q.take(); inside while loop on Worker's run method. thus those Worker threads are forever waiting for new Integers to be put on the queue.
Suggestions: You can use Eclipse Java IDE to debug and see whats actually going on each thread

Learning about Threads

I have written a simple program, that is intended to start a few threads. The threads should then pick a integer n from an integer array, use it to wait n and return the time t the thread waited back into an array for the results.
If one thread finishes it's task, it should pick the next one, that has not yet being assigned to another thread.
Of course: The order in the arrays has to be maintained, so that integers and results match.
My code runs smoothly as far I see.
However I use one line of code block I find in particular unsatisfying and hope there is a good way to fix this without changing too much:
while(Thread.activeCount() != 1); // first evil line
I kinda abuse this line to make sure all my threads finish getting all the tasks done, before I access my array with the results. I want to do that to prevent ill values, like 0.0, Null Pointer Exception... etc. (in short anything that would make an application with an actual use crash)
Any sort of constructive help is appreciated. I am also not sure, if my code still runs smoothly for very very long arrays of tasks for the threads, for example the results no longer match the order of the integer.
Any constructive help is appreciated.
First class:
public class ThreadArrayWriterTest {
int[] repitions;
int len = 0;
double[] timeConsumed;
public boolean finished() {
synchronized (repitions) {
return len <= 0;
}
}
public ThreadArrayWriterTest(int[] repitions) {
this.repitions = repitions;
this.len = repitions.length;
timeConsumed = new double[this.len];
}
public double[] returnTimes(int[] repititions, int numOfThreads, TimeConsumer timeConsumer) {
for (int i = 0; i < numOfThreads; i++) {
new Thread() {
public void run() {
while (!finished()) {
len--;
timeConsumed[len] = timeConsumer.returnTimeConsumed(repititions[len]);
}
}
}.start();
}
while (Thread.activeCount() != 1) // first evil line
;
return timeConsumed;
}
public static void main(String[] args) {
long begin = System.currentTimeMillis();
int[] repitions = { 3, 1, 3, 1, 2, 1, 3, 3, 3 };
int numberOfThreads = 10;
ThreadArrayWriterTest t = new ThreadArrayWriterTest(repitions);
double[] times = t.returnTimes(repitions, numberOfThreads, new TimeConsumer());
for (double d : times) {
System.out.println(d);
}
long end = System.currentTimeMillis();
System.out.println("Total time of execution: " + (end - begin));
}
}
Second class:
public class TimeConsumer {
double returnTimeConsumed(int repitions) {
long before = System.currentTimeMillis();
for (int i = 0; i < repitions; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long after = System.currentTimeMillis();
double ret = after - before;
System.out.println("It takes: " + ret + "ms" + " for " + repitions + " runs through the for-loop");
return ret;
}
}
The easiest way to wait for all threads to complete is to keep a Collection of them and then call Thread.join() on each one in turn.
In addition to .join() you can use ExecutorService to manage pools of threads,
An Executor that provides methods to manage termination and methods
that can produce a Future for tracking progress of one or more
asynchronous tasks.
An ExecutorService can be shut down, which will cause it to reject new
tasks. Two different methods are provided for shutting down an
ExecutorService. The shutdown() method will allow previously submitted
tasks to execute before terminating, while the shutdownNow() method
prevents waiting tasks from starting and attempts to stop currently
executing tasks. Upon termination, an executor has no tasks actively
executing, no tasks awaiting execution, and no new tasks can be
submitted. An unused ExecutorService should be shut down to allow
reclamation of its resources.
Method submit extends base method Executor.execute(Runnable) by
creating and returning a Future that can be used to cancel execution
and/or wait for completion. Methods invokeAny and invokeAll perform
the most commonly useful forms of bulk execution, executing a
collection of tasks and then waiting for at least one, or all, to
complete.
ExecutorService executorService = Executors.newFixedThreadPool(maximumNumberOfThreads);
CompletionService completionService = new ExecutorCompletionService(executorService);
for (int i = 0; i < numberOfTasks; ++i) {
completionService.take();
}
executorService.shutdown();
Plus take a look at ThreadPoolExecutor
Since java provides more advanced threading API with concurrent package, You should have look into ExecutorService, which simplifies thread management mechanism.
Simple to solution to your problem.
Use Executors API to create thread pool
static ExecutorService newFixedThreadPool(int nThreads)
Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue.
Use invokeAll to wait for all tasks to complete.
Sample code:
ExecutorService service = Executors.newFixedThreadPool(10);
List<MyCallable> futureList = new ArrayList<MyCallable>();
for ( int i=0; i<12; i++){
MyCallable myCallable = new MyCallable((long)i);
futureList.add(myCallable);
}
System.out.println("Start");
try{
List<Future<Long>> futures = service.invokeAll(futureList);
for(Future<Long> future : futures){
try{
System.out.println("future.isDone = " + future.isDone());
System.out.println("future: call ="+future.get());
}
catch(Exception err1){
err1.printStackTrace();
}
}
}catch(Exception err){
err.printStackTrace();
}
service.shutdown();
Refer to this related SE question for more details on achieving the same:
wait until all threads finish their work in java

How to pass an integer/other variables between threads in java?

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.

How to make sure all the subclass threads exited ?

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.

Categories

Resources