Make one thread wait for another to finish - java

I have two thread classes: one that prints numbers from 0 to 9, and another from 100 to 109. What I want is to make the first thread wait for the other one to finish. For this, I used the join() method, but it's not working. Please tell me where I'm going wrong:
//demonstrates the use of join() to wait for another thread to finish
class AThread implements Runnable {
Thread t;
AThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=0; i<10; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
public void halt(Thread th) {
try {
th.join();
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
//a different thread class (we distinguish threads by their output)
class BThread implements Runnable {
Thread t;
BThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=100; i<110; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
public class WaitForThread {
public static void main(String[] args) {
AThread t1 = new AThread();
BThread t2 = new BThread();
t1.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
t2.t.start();
}
}

You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:
Thread.join()
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
Thread.isAlive()
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
Reorder the statements in your main method
t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
edit to answer your questions in the comments:
If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:
class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;
AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}
public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();
// ...
}
// ...
}
public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);
t2.t.start();
t1.t.start();
}
}

Related

Unexpected behaviour of Threads

I am trying to achieve that thread2 should complete first, then thread1, For this O am using join() method. But if I uncomment the System.out.println() present in the try block of thread1 class. then
code give null pointer exception. Why in try block I need to add line, it doesn't make any sense that adding a line code start working.
Demo class
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
Thread1 class
public class Thread1 extends Thread {
#Override
public void run() {
try {
// System.out.println(); // on adding anyline, this whole code works!!, uncommenting this line of code give NPE
Thread2.fetcher.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread2 class
public class Thread2 extends Thread {
static Thread fetcher;
#Override
public void run() {
fetcher= Thread.currentThread(); // got the thread2
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
OUTPUT of the program
in thread2 class Thread-2
Exception in thread "Thread-0" java.lang.NullPointerException
at org.tryout.Thread1.run(Thread1.java:22)
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
It is working purely by "pure luck" the
System.out.println();
internally calls synchronized, which is working as a delay that gives enough time for Thread 2 its field fetcher in:
fetcher= Thread.currentThread(); // got the thread2
In order to avoid this race-condition you need to ensure that the Thread 2 sets the field fetcher before Thread 1 accesses it. For that you case use, among others, a 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.
First, create a barrier for the number of threads that will be calling it, namely 2 threads:
CyclicBarrier barrier = new CyclicBarrier(2);
With the CyclicBarrier you can then force Thread 1 to wait for Thread 2 before accessing its field fetcher:
try {
barrier.await(); // Let us wait for Thread 2.
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
Thread 2 also calls the barrier after having setting up the field fetcher, accordingly:
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
Both threads will continue their work as soon as both have called the barrier.
An example:
public class Demo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread1 t1 = new Thread1(barrier);
Thread2 t2 = new Thread2(barrier);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final CyclicBarrier barrier;
public Thread1(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
try {
barrier.await();
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
static Thread fetcher;
final CyclicBarrier barrier;
public Thread2(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
If your code is not for education purposes, and you are not force to use any particular synchronization mechanism for learning purposes. In the current context you can simply pass the thread 2 as parameter of the thread 1, and call join directly on it as follows:
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1(t2);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final Thread thread2;
public Thread1(Thread thread2){
this.thread2 = thread2;
}
#Override
public void run() {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This should allow your code to work properly. There is insufficient time between thread startups to allow fletcher to initialize.
try {
Thread.sleep(500);
Thread2.fetcher.join();
} catch (InterruptedException ie) {
}
For something this simple, the sleep should work. But for more complicated threads, appropriate synchronization is the key. And you should be aware that thread programming can be one of the most difficult aspects of programming to debug.

wait for N-1 out of N threads to end, then issue an instruction for the last thread

So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}

How can I start a thread from another and restart a thread after execution?

I have 2 threads, the "main" thread which starts a secondary thread to run a little process.
The "main" thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the "main" thread must start again no matter what happened with the process of the secondary thread.
If the secondary process ended earlier, the "main" thread must start to work again.
How can I start a thread from another, wait for the end of execution, and restart the thread after?
I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess
public class ExampleRun {
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}
public class MyProcess extends Thread {
public void run() {
System.out.println("start");
synchronized (this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("I sleep");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Wake up");
notify();
}
}
}
The simplest way to achieve what you want is to use Thread.join(timeout).
Also, do not use synchronized, wait, or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.
Here's what your main program would look like:
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
try {
t.join(10000L);
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("Main thread resumes");
}
Note that when the main thread resumes after the join() call, it can't tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive().
Your child thread of course could do anything, but it's important for it not to use synchronized, wait, or notify on itself. For example, here's a rewrite that avoids using these calls:
class MyProcess extends Thread {
public void run() {
System.out.println("MyProcess starts");
for (int i = 0; i < 5; i++) {
try {
System.out.println("MyProcess sleeps");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyProcess finishes");
}
}
You can do this with a simple lock method:
public static void main (String[] args)
{
// create new lock object
Object lock = new Object();
// create and start thread
Thread t = new Thread(() ->
{
// try to sleep 1 sec
try { Thread.sleep(1000); }
catch (InterruptedException e) { /* do something */ }
// notify main thread
synchronized (lock) { lock.notifyAll(); }
};
t.start();
// wait for second thread to finish
synchronized (lock)
{
while (t.isAlive())
lock.wait();
}
// second thread finished
System.out.println("second thread finished :)");
}
You could call Thread.join() on the Thread you want to wait for, per the Javadoc,
Waits for this thread to die.
Alternatively, you could use a Future and simply call get(), from its' Javadoc,
Waits if necessary for the computation to complete, and then retrieves its result.

Having troubles with threads and semaphors in JAVA

I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.

Running the more than two threads in a particular order

I want the threads to run in a particular order. Suppose I have three thread T1, T2, T2 .
T1 prints 0
T2 prints 1
T3 prints 2
I want the output in the order 0 1 2, 0 1 2 for certain number of time.
If there are two threads T1 and T2. Printing 0 1, 0 1... can be done using Producer-Consumer Problem using synchronization.
Create a class UnitOfWork:
public class UnitOfWork implements Runnable
{
String text;
public UnitOfWork(String text){
this.text = text;
}
public void run(){
System.out.println(text);
}
}
And then create a single thread executor service:
ExecutorService executor = ExecutorService.newSingleThreadExecutor();
which you will use like this:
UnitOfWork uow0 = new UnitOfWork("0");
UnitOfWork uow1 = new UnitOfWork("1");
UnitOfWork uow2 = new UnitOfWork("2");
for(int i = 0; i < 5; i++){
executor.submit(uow0);
executor.submit(uow1);
executor.submit(uow2);
}
When you are unhappy with the single thread, you can start using multiple thread executor service, which will in fact run tasks concurrently.
Using the method join() in the thread class you can achieve this.
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.
Like sleep, join responds to an interrupt by exiting with an InterruptedException.
Use Thread.join to ensure it terminates before the next thread starts.
public static void main(String[] args) throws InterruptedException {
final Thread th1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th2 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
th1.start();
th1.join();
th2.start();
th2.join();
th3.start();
}
This is a minimalist piece of code which does literally what you asked for. It relies on the wait-notify mechanism.
I stand by my assesment that you do not need any threads to meet your requirement. A simple loop which prints 0-1-2 is all you really need.
import static java.lang.Thread.currentThread;
public class A {
static int coordinator, timesPrinted;
static final int numThreads = 3, timesToPrint = 300;
public static void main(String[] args) {
for (int i = 0; i < numThreads; i++) {
final int myId = i;
new Thread(new Runnable() { public void run() {
while (true) synchronized (A.class) {
if (coordinator%numThreads == myId) {
System.out.println(myId+1);
coordinator++;
if (timesPrinted++ > timesToPrint) currentThread().interrupt();
A.class.notifyAll();
}
try {A.class.wait();} catch (InterruptedException e) {break;}
}
}}).start();
}
}
}

Categories