Custom Way to Wait for all thread to complete in Java? - 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);
}
}

Related

Thread does not stop after interruption

I have a problem that a threads do not stop after I call .interrupt() method. There is a code snippet
for (Thread t : letters.getThreads()) t.start();
Thread.sleep(5000);
for (Thread t : letters.getThreads()) t.interrupt();
There getThreads() method is from class Letters (letters is an object of the class) and it returns array of Thread objects. Here you have body of the method from Letters class:
public Thread[] getThreads() {
Thread[] threads = new Thread[letters.length];
for(int i = 0; i < threads.length; i++) {
threads[i] = new Thread( () -> {
while(true) {
try {
System.out.print("a");
Thread.sleep(1000);
} catch (InterruptedException ex) {
return;
}
}
}
,"Thread " + letters[i]); //letters[] is a local array.
}
return threads;
}
and in this case I described, threads do not stop working, but when I do everything in main mathod ( array of Threads objects ) it works properly. Why is this happening?
In the getThreads() method, you create new threads. First call create new threads and started them. However the 2nd call also create new threads but never started hence interrupt non-running threads doesn't work?

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.

Prohibiting One Task when another is running

So let's say I'm creating and starting a bunch of threads in a for loop, that is being executed in the run method of a launcher thread. Let's also say that I want to be able to interrupt the launcher thread and all threads that the thread has created, and I do this through a button.
So something like this -
try{
for(int i = 0; i < n;i++){
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
currThread.start();
}
} catch (InterruptedException e){
e.printStackTrace();
}
BUTTON-
public void actionPerformed(ActionEvent arg0) {
List<Worker> threads = launchThread.getWorkerThreads();
for(int i = 0; i < threads.size();i++){
threads.get(i).interrupt();
}
launchThread.interrupt();
}
Now, let's say that I want to make it so that the interrupts cannot occur at the same time as thread creation. I think a way to do this would be to construct a dummy object and put both pieces of code inside a lock
synchronized(dummyObject){
//thread creation or interruption code here (shown above)
}
Will this way work? I ask because I'm not sure how to test to see if it will.
Start the threads separately from creating them.
for(int i = 0; i < n; i++) {
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
}
// later
for (Worker w : workerThreads) {
w.start();
}
If that's still not enough, your dummyObject synchronization should work just fine.
// You probably need to make this a (private final) field
Object lock = new Object();
// later
synchronized (lock) {
for(int i = 0; i < n; i++) {
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
w.start();
}
}
// later still
public void actionPerformed(ActionEvent arg0) {
synchronized (lock) {
// interruption code here
}
}
The concept of synchronization remains the same however complicated are the underlying operations to be executed.
As you specified, there are two types of mutually exclusive tasks (thread creation and interruption). So locking is pretty much the canonical tool for the job.

How to join one thread with other in 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.

Categories

Resources