Printing values from different threads using wait and notify - java

I have three threads ThreadA, ThreadB and ThreadC printing values A, B and C respectively in loop.I want output to be like A,B,C and then again A, B and C till loops are executing in threads.I want to write this sample program using wait and notify. Below code is printing the desired output but sometimes I am just seeing "A" in output, I am not able to figure out the case.
public class ThreadOrder {
public static void main(String[] args) {
Object lockAB = new Object();
Object lockBC = new Object();
Object lockCA = new Object();
Thread threadA = new Thread(new ThreadOrder().new ThreadA(lockAB, lockCA));
Thread threadB = new Thread(new ThreadOrder().new ThreadB(lockAB, lockBC));
Thread threadC = new Thread(new ThreadOrder().new ThreadC(lockBC, lockCA));
threadA.start();
threadB.start();
threadC.start();
}
class ThreadA implements Runnable {
Object lockAB;
Object lockCA;
public ThreadA(Object lockAB, Object lockCA) {
this.lockAB = lockAB;
this.lockCA = lockCA;
}
#Override
public void run() {
for(int i=0; i<3; i++) {
if(i!=0) {
try {
synchronized (lockCA) {
lockCA.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A");
synchronized (lockAB) {
lockAB.notify();
}
}
}
}
class ThreadB implements Runnable {
Object lockAB;
Object lockBC;
public ThreadB(Object lockAB, Object lockBC) {
this.lockAB = lockAB;
this.lockBC = lockBC;
}
#Override
public void run() {
for(int i=0; i<3; i++) {
try {
synchronized (lockAB) {
lockAB.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
synchronized (lockBC) {
lockBC.notify();
}
}
}
}
class ThreadC implements Runnable {
Object lockBC;
Object lockCA;
public ThreadC(Object lockBC, Object lockCA) {
this.lockBC = lockBC;
this.lockCA = lockCA;
}
#Override
public void run() {
for(int i=0; i<3; i++) {
try {
synchronized (lockBC) {
lockBC.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("C");
synchronized (lockCA) {
lockCA.notify();
}
}
}
}
}

You call wait, but you haven't tested if there's anything to wait for. You call notify, but you haven't changed anything that you would need to notify another thread about. You have all these synchronized methods, but no shared state for the synchronization to protect.
Nothing in your code makes any sense and it seems that you fundamentally don't understand what the wait/notify mechanism does. The wait function allows a thread to wait for some shared state to change, and the notify function allows one thread to tell others that some shared state has changed. But there has to be some shared state because the wait/notify mechanism (unlike a lock or sempahore) is internally stateless.
You should probably have some shared state protected by the synchronization. It should encode which thread should go next. If you need to print, but the shared state says it's not your turn, then you have something to wait for. When you print and make it some other thread's turn to print next, then you have something to notify other threads about.

Consider creating a ring of threads connected to one another by blocking queues. Then you can pass a token around the ring. Each thread waits to receive the token, prints its output, passes the token on to the next thread in the ring, and goes back to waiting.

package com.test.algorithms;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class PrintInOrder {
private static Integer[] a = { 1, 1, 1 };
private static Integer[] b = { 2, 2, 2 };
private static Integer[] c = { 3, 3, 3 };
private static Integer[] d = { 4, 4, 4 };
public static void main(String[] args) throws InterruptedException {
QueueOrder q1 = null;
QueueOrder q2 = null;
QueueOrder q3 = null;
QueueOrder q4 = null;
q1 = new QueueOrder(a);
q2 = new QueueOrder(b);
q3 = new QueueOrder(c);
q4 = new QueueOrder(d);
q1.setChild(q2);
q2.setChild(q3);
q3.setChild(q4);
q4.setChild(q1);
Thread t1 = new Thread(q1);
Thread t2 = new Thread(q2);
Thread t3 = new Thread(q3);
Thread t4 = new Thread(q4);
t1.start();
t2.start();
t3.start();
t4.start();
QueueOrder q = q1;
while (!q.queue.isEmpty()) {
synchronized (q) {
if (!q.isPrinted) {
q.notify();
q.wait();
}
}
q = q.child;
}
t1.join();
t2.join();
t3.join();
t4.join();
}
}
class QueueOrder implements Runnable {
Integer[] arr;
QueueOrder child;
Queue<Integer> queue = new LinkedList<>();
boolean isPrinted = false;
QueueOrder(Integer[] arr) {
this.arr = arr;
queue.addAll(Arrays.asList(arr));
}
public QueueOrder getChild() {
return child;
}
public void setChild(QueueOrder child) {
this.child = child;
}
public void run() {
while (!this.queue.isEmpty()) {
synchronized (this) {
if (!this.isPrinted) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print("**" + this.queue.poll());
this.isPrinted = false;
synchronized (this) {
this.notify();
}
}
}
}

package com.test.algorithms;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class PrintInOrder1 {
private static Integer[] a = { 1, 1, 1 };
private static Integer[] b = { 2, 2, 2 };
private static Integer[] c = { 3, 3, 3 };
private static Integer[] d = { 4, 4, 4 };
public static void main(String[] args) throws InterruptedException {
QueueOrder1 q1 = null;
QueueOrder1 q2 = null;
QueueOrder1 q3 = null;
QueueOrder1 q4 = null;
q1 = new QueueOrder1(a);
q2 = new QueueOrder1(b);
q3 = new QueueOrder1(c);
q4 = new QueueOrder1(d);
q1.setChild(q2);
q1.isPrinted = true;
q2.setChild(q3);
q3.setChild(q4);
q4.setChild(q1);
Thread t1 = new Thread(q1);
Thread t2 = new Thread(q2);
Thread t3 = new Thread(q3);
Thread t4 = new Thread(q4);
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
}
}
class QueueOrder1 implements Runnable {
Integer[] arr;
QueueOrder1 child;
Queue<Integer> queue = new LinkedList<>();
boolean isPrinted = false;
QueueOrder1(Integer[] arr) {
this.arr = arr;
queue.addAll(Arrays.asList(arr));
}
public QueueOrder1 getChild() {
return child;
}
public void setChild(QueueOrder1 child) {
this.child = child;
}
public void run() {
while (!this.queue.isEmpty()) {
synchronized (this) {
if (!this.isPrinted) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print("**" + this.queue.poll());
this.isPrinted = false;
synchronized (this.child) {
if(!this.child.isPrinted) {
this.child.notify();
}
}
}
}
}

Related

Multi threaded java program to print even and odd numbers alternatively

I was asked to write a two-threaded Java program in an interview. In this program one thread should print even numbers and the other thread should print odd numbers alternatively.
Sample output:
Thread1: 1
Thread2: 2
Thread1: 3
Thread2: 4
... and so on
I wrote the following program. One class Task which contains two methods to print even and odd numbers respectively. From main method, I created two threads to call these two methods. The interviewer asked me to improve it further, but I could not think of any improvement. Is there any better way to write the same program?
class Task
{
boolean flag;
public Task(boolean flag)
{
this.flag = flag;
}
public void printEven()
{
for( int i = 2; i <= 10; i+=2 )
{
synchronized (this)
{
try
{
while( !flag )
wait();
System.out.println(i);
flag = false;
notify();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
public void printOdd()
{
for( int i = 1; i < 10; i+=2 )
{
synchronized (this)
{
try
{
while(flag )
wait();
System.out.println(i);
flag = true;
notify();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
public class App {
public static void main(String [] args)
{
Task t = new Task(false);
Thread t1 = new Thread( new Runnable() {
public void run()
{
t.printOdd();
}
});
Thread t2 = new Thread( new Runnable() {
public void run()
{
t.printEven();
}
});
t1.start();
t2.start();
}
}
I think this should work properly and pretty simple.
package com.simple;
import java.util.concurrent.Semaphore;
/**
* #author Evgeny Zhuravlev
*/
public class ConcurrentPing
{
public static void main(String[] args) throws InterruptedException
{
Semaphore semaphore1 = new Semaphore(0, true);
Semaphore semaphore2 = new Semaphore(0, true);
new Thread(new Task("1", 1, semaphore1, semaphore2)).start();
new Thread(new Task("2", 2, semaphore2, semaphore1)).start();
semaphore1.release();
}
private static class Task implements Runnable
{
private String name;
private long value;
private Semaphore semaphore1;
private Semaphore semaphore2;
public Task(String name, long value, Semaphore semaphore1, Semaphore semaphore2)
{
this.name = name;
this.value = value;
this.semaphore1 = semaphore1;
this.semaphore2 = semaphore2;
}
#Override
public void run()
{
while (true)
{
try
{
semaphore1.acquire();
System.out.println(name + ": " + value);
value += 2;
semaphore2.release();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
}
}
Well, there are many alternatives. I would probably use a SynchronousQueue instead (I don't like low-level wait/notify and try to use higher-level concurrency primitives instead). Also printOdd and printEven could be merged into single method and no additional flags are necessary:
public class App {
static class OddEven implements Runnable {
private final SynchronousQueue<Integer> queue = new SynchronousQueue<>();
public void start() throws InterruptedException {
Thread oddThread = new Thread(this);
Thread evenThread = new Thread(this);
oddThread.start();
queue.put(1);
evenThread.start();
}
#Override
public void run() {
try {
while (true) {
int i = queue.take();
System.out.println(i + " (" + Thread.currentThread() + ")");
if (i == 10)
break;
queue.put(++i);
if (i == 10)
break;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws InterruptedException {
new OddEven().start();
}
}
Is there any better way to write the same program?
Well, the thing is, the only good way to write the program is to use a single thread. If you want a program to do X, Y, and Z in that order, then write a procedure that does X, then Y, then Z. There is no better way than that.
Here's what I would have written after discussing the appropriateness of threads with the interviewer.
import java.util.concurrent.SynchronousQueue;
import java.util.function.Consumer;
public class EvenOdd {
public static void main(String[] args) {
SynchronousQueue<Object> q1 = new SynchronousQueue<>();
SynchronousQueue<Object> q2 = new SynchronousQueue<>();
Consumer<Integer> consumer = (Integer count) -> System.out.println(count);
new Thread(new Counter(q1, q2, 2, 1, consumer)).start();
new Thread(new Counter(q2, q1, 2, 2, consumer)).start();
try {
q1.put(new Object());
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
private static class Counter implements Runnable {
final SynchronousQueue<Object> qin;
final SynchronousQueue<Object> qout;
final int increment;
final Consumer<Integer> consumer;
int count;
Counter(SynchronousQueue<Object> qin, SynchronousQueue<Object> qout,
int increment, int initial_count,
Consumer<Integer> consumer) {
this.qin = qin;
this.qout = qout;
this.increment = increment;
this.count = initial_count;
this.consumer = consumer;
}
public void run() {
try {
while (true) {
Object token = qin.take();
consumer.accept(count);
qout.put(token);
count += increment;
}
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
How about a shorter version like this:
public class OddEven implements Runnable {
private static volatile int n = 1;
public static void main(String [] args) {
new Thread(new OddEven()).start();
new Thread(new OddEven()).start();
}
#Override
public void run() {
synchronized (this.getClass()) {
try {
while (n < 10) {
this.getClass().notify();
this.getClass().wait();
System.out.println(Thread.currentThread().getName() + ": " + (n++));
this.getClass().notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
There is a bit of a trick to kick-start the threads properly - thus the need to an extra notify() to start the whole thing (instead of have both processes wait, or required the main Thread to call a notify) and also to handle the possibility that a thread starts, does it's work and calls notify before the second thread has started :)
My initial answer was non-functional. Edited:
package test;
public final class App {
private static volatile int counter = 1;
private static final Object lock = new Object();
public static void main(String... args) {
for (int t = 0; t < 2; ++t) {
final int oddOrEven = t;
new Thread(new Runnable() {
#Override public void run() {
while (counter < 100) {
synchronized (lock) {
if (counter % 2 == oddOrEven) {
System.out.println(counter++);
}
}
}
}
}).start();
}
}
}

How to make N Threads take turns in cyclic manner in Java?

I recently went through this question on Stackoverflow, where problem is to print even and odd in two threads, in such a manner that they are printed in incremental order. The question is here, where I have provided one solution. This led me to think, what should we do, if we need N Threads to take turn in cyclical manner, in a predefined order ? I tried using CyclicBarrier for this. This is my code :
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class NThreadTurnTaking {
public static void main(String[] args) {
NThreadTurnTaking nThreadTurnTaking = new NThreadTurnTaking();
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
NThreadTurnTaking.A a = nThreadTurnTaking.new A(cyclicBarrier);
NThreadTurnTaking.B b = nThreadTurnTaking.new B(cyclicBarrier);
NThreadTurnTaking.C c = nThreadTurnTaking.new C(cyclicBarrier);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
Thread t3 = new Thread(c);
t1.start();
t2.start();
t3.start();
}
class A implements Runnable{
private final CyclicBarrier cyclicBarrier;
public A(CyclicBarrier cyclicBarrier) {
super();
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("A");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable{
private final CyclicBarrier cyclicBarrier;
public B(CyclicBarrier cyclicBarrier) {
super();
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("B");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class C implements Runnable{
private final CyclicBarrier cyclicBarrier;
public C(CyclicBarrier cyclicBarrier) {
super();
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("C");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
}
I want my program to print A->B->C in order. While using a CyclicBarrier does ensure that they are printed one after another, but the order is not being maintained, which is obvious, because I am not doing anything particular to tell my program that I want a specific order. This is the output :
B
C
A
A
C
B
B
A
C.....
So, how do we ensure order here ? Kindly help.

Cyclic Barrier in java

I have a list which needs to be populated by three parties(threads,lets say).I am using cyclic barrier to achieve this functionality. Everything works fine except that I am not able to use the resulted list without inducing a forced sleep. Below is the code :
public class Test{
List<Integer> item = new Vector<Integer>();
public void returnTheList(){
CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
#Override
public void run() {
System.out.println("All parties are arrived at barrier, lets play -- : " + CyclicBarrierTest.getTheList().size());
//Here I am able to access my resulted list
}
});
CyclicBarrierTest sw1 = new CyclicBarrierTest(cb, new ZetaCode(1500), s);
CyclicBarrierTest sw2 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
CyclicBarrierTest sw3 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
Thread th1 = new Thread(sw1, "ZetaCode1");
Thread th2 = new Thread(sw2, "ZetaCode2");
Thread th3 = new Thread(sw3, "ZetaCode3");
th1.start();
th2.start();
th3.start();
}
public static void main(String args[]){
System.out.println("asdfasd");
Test test = new Test();
//ActionClass ac = new ActionClass();
test.returnTheList();
System.out.println("Inside the main method...size of the final list : " +test.item.size() );
}
Below is my CyclicBrrierTest class :
public class CyclicBarrierTest implements Runnable{
private CyclicBarrier barrier;
private Object obj;
static volatile String s = "";
volatile List<Integer> finalIntList = new Vector<Integer>();
public CyclicBarrierTest(CyclicBarrier barrier, Object obj, String s){
this.barrier = barrier;
this.obj = obj;
}
#Override
public void run(){
try{
System.out.println(Thread.currentThread().getName() + " is waiting on barrier and s is now : " + finalIntList.size());
ZetaCode simple = (ZetaCode)obj;
finalIntList.addAll(simple.getTheItemList());
barrier.await();
System.out.println(Thread.currentThread().getName() + " has crossed the barrier");
}catch(InterruptedException ex){
System.out.println("Error.." + ex.getMessage());
}catch(Exception e){
System.out.println("Error.." + e.getMessage());
}
}
public List<Integer> getTheList(){
return finalIntList;
}
So if I run this code without giving any delay the print statement in my main method gives me the length of my list as zero,however after giving an appropriate sleep it gives me the expected output.I want to achieve the same without giving any delay.Any help would be appreciated.
Thanks in advance.
It seems you'd want to use a CountDownLatch, not a CyclicBarrier here. The CyclicBarrier is working exactly as intended - your main method just isn't waiting for it to be tripped by all 3 threads. When you give it a sleep statement, the other 3 threads just happen to finish before main wakes up again.
A CyclicBarrier is useful when you need N workers to all reach the same 'checkpoint' before proceeding, and the workers themselves are the only ones who care. However, you have an N + 1 user here, the main thread, who wants to know when they're all done, and CyclicBarrier doesn't support that use case.
Note, of course that you can also use both of them.
In this code we have 4 tasks . Task1, Task2, Task3 producing int values and Task4 will add all the int values . Task4 is waiting after calling await() for Task1, Task2, Task3 to produce values.When they produce values they call await() method and Task 4 will add their values and print the o/p and call reset() method so the barrier will reset. After reset this process will continue again
package practice;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicbarrierExample {
public static void main(String[] args) {
CyclicBarrier c = new CyclicBarrier(4);
Task1 t1 = new Task1(c);
Task2 t2 = new Task2(c);
Task3 t3 = new Task3(c);
Task4 t4 = new Task4(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Task1 extends Thread {
CyclicBarrier c;
static int t1 ;
public Task1(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t1 = t1 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Task2 extends Thread {
CyclicBarrier c;
static int t2;
public Task2(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t2 = t2 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class Task3 extends Thread {
CyclicBarrier c;
static int t3;
public Task3(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t3 = t3 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class Task4 extends Thread {
CyclicBarrier c;
static int t4;
static int count=0;
public Task4(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (count<10) {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
t4 = Task1.t1 + Task2.t2 + Task3.t3;
System.out.println(t4);
try {
c.reset();
} catch (Exception e) {
System.out.println("yo");
}
count++;
}
}
}

Interview: How to ensure that a thread runs after another?

There are thread T1, T2 and T3, how can we ensure that thread T2 run after T1 and thread T3 run after T2?
This question was asked in my interview. I didn't answer. Please explain in detail.
This would be the simplest, dumbest approach:
final Thread t1 = new Thread(new T1()); // assume T1 is a Runnable
t1.start();
t1.join();
final Thread t2 = new Thread(new T2());
t2.start();
t2.join();
final Thread t3 = new Thread(new T3());
t3.start();
t3.join();
The obvious, and simplest, way has already been posted by #Assylias - have T1 run method create/start T2 and T2 run method create/start T3.
It is, IMHO, verging on pointless, but it could be done.
Solutions using Join() do not answer the question - they ensure that the termination of the threads is ordered, not the running of them. If the interviewr does not get that, you need to find another job anyway.
In an interview, my answer would be 'For * sake why? Threads are ususally used to avoid exactly what you are asking!'.
One way to do it would be something like the following. It's complex though. You might want to use the java.util.concurrent.CyclicBarrier class for this.
Each thread when it finishes sets the boolean value and notifies the next thread to continue. Even though it is an AtomicBoolean class, we need the synchronized so we can wait() and notify() on it.
It would be cleaner to pass in the lock objects or maybe have a begin() method on T2 and T3 so we can hide the locks inside of those objects.
final Object lock2 = new Object();
final Object lock3 = new Object();
boolean ready2;
boolean ready3;
...
public T1 implements Runnable {
public void run() {
...
synchronized (lock2) {
// notify the T2 class that it should start
ready2 = true;
lock2.notify();
}
}
}
...
public T2 implements Runnable {
public void run() {
// the while loop takes care of errant signals
synchronized (lock2) {
while (!ready2) {
lock2.wait();
}
}
...
// notify the T3 class that it should start
synchronized (lock3) {
ready3 = true;
lock3.notify();
}
}
}
...
public T3 implements Runnable {
public void run() {
// the while loop takes care of errant signals
synchronized (lock3) {
while (!ready3) {
lock3.wait();
}
}
...
}
}
There are thread T1, T2 and T3, how can we ensure that thread T2 run
after T1 and thread T3 run after T2?
OR
There are three threads T1, T2 and T3? How do you ensure sequence T1, T2, T3 in Java?
The question basically is T3 should finish first , T2 second and T1 last.
We can use use join() method of thread class.
To ensure three threads execute you need to start the last one first e.g. T3 and then call join methods in reverse order e.g. T3 calls T2.join,
and T2 calls T1.join. In this way, T1 will finish first and T3 will finish last.
public class Test1 {
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("start 1");
System.out.println("end 1");
}//run
});
final Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println(" start 2 ");
try {
t1.join(2000);
} catch (Exception e) {
e.getStackTrace();
}
System.out.println(" end 2");
}
}) ;
final Thread t3 = new Thread( new Runnable() {
public void run() {
System.out.println(" start 3 ");
try {
t2.join(4000);
}catch(Exception e) {
e.getStackTrace();
}
System.out.println(" end 3 ");
}
});
// we are reversing the order of the start() method
t3.start();
t2.start();
t1.start();
}
}
From the output, You can see that threads have started in different order as you don't know which thread will get CPU. Its the decision of the Thread Scheduler, so we cannot do anything. But, you can see that threads are finished in correct order i.e. T1 then T2 and then T3.
There is another way of doing it. The pseudo code is :
t1.start();
t1.join(); // signals t2 to wait
if( !t1.isAlive()) {
t2.start();// if t1 is finished then t2 will start
}
t2.join();//signals t3 to wait
if (!t2.isAlive()) {
t3.start();
}
Let's take a full program:
public class Tic implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("tic");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class Tac implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("tac");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class Toe implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("toe");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class RunThreads1 {
public static void main(String[] args) {
try {
Tic tic = new Tic();
Tac tac = new Tac();
Toe toe = new Toe();
Thread t1 = new Thread(tic);
Thread t2 = new Thread(tac);
Thread t3 = new Thread(toe);
t1.start();
t1.join(); // signals t2 to wait
if( !t1.isAlive()) {
t2.start();// if t1 is finished then t2 will start
}
t2.join();//signals t3 to wait
if (!t2.isAlive()) {
t3.start();
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
The output is :
tic
tic
tac
tac
toe
toe
At the start of each thread (except t1), make it call join() on it's predecessor. Using executors (instead of threads directly) is another option. One could also look at using semaphores - T1 should release the permit upon completion, T2 should try to acquire two permits, and release them when done, T3 should try to acquire three permits & so on. Using join or executors would be the preferred route.
Threads are also runnables. You can simply run them sequentially:
t1.run();
t2.run();
t3.run();
This has obviously little interest.
Assuming they want the threads to run in parallel, one solution would be to have each thread start the next one, since the JMM guarantees that:
A call to start() on a thread happens-before any actions in the started thread.
Guess what interviewer asking was three threads do the work in sequence.For example if one thread prints 1,4,5...second 2,5,8 and thirds 3,6,9 etc..ur output should be 1,2,3,4,5.....
Ist thread prints 1 and gives chance to 2nd thread to print 2..etc.,
I tried it using cyclebarriers.As soon as 'one' prints 1it gives chance to two as it calls cb.wait,when two runs it will in turn call three in similar fashion and it will continue.Let me know if thr are any bugs in the code
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class one implements Runnable{
CyclicBarrier cb;
one(CyclicBarrier cb){this.cb=cb;}
public void run(){
int i=1;
while(true)
{
System.out.println(i);
try {
Thread.sleep(1000);
cb.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i=i+3;
}
}
}
class two implements Runnable{
CyclicBarrier cb;
int i=2;
two(CyclicBarrier cb){this.cb=cb;}
public void run(){
System.out.println(i);
try {
cb.await();
i=i+3;
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class oneTwoThree {
public static void main(String args[]){
Runnable threePrinter = new Runnable() {
int i=3;
public void run() {
System.out.println(i);
i=i+3;
}
};
CyclicBarrier bar2 =new CyclicBarrier(1,threePrinter);//, barrier1Action);
two twoPrinter =new two(bar2);
CyclicBarrier bar1 =new CyclicBarrier(1,twoPrinter);
Thread onePrinter=new Thread(new one(bar1));
onePrinter.start();
}
}
I tried in a much simpler way.. using a waits and notifies.(as opposed to cyclic barrier approach in my prev post).
It uses a 'State' class... which gets three states:1,2,3.(default 3).
When it is at 3, it triggers t1, at 1 will trigger t2, at 2 will trigger t3 and so on.
Classes:
State// int i=3
T1// prints 1,4,7...
T2// Prints 2,5,8
T3//Prints 3,6,9 etc.,
Please let me know your views or if any issues in the code. Thanks.
Here is the code.:
public class State {
private int state ;
public State() {
this.state =3;
}
public synchronized int getState() {
return state;
}
public synchronized void setState(int state) {
this.state = state;
}
}
public class T1 implements Runnable {
State s;
public T1(State s) {
this.s =s;
}
#Override
public void run() {
int i =1;
while(i<50)
{
//System.out.println("s in t1 "+ s.getState());
while(s.getState() != 3)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==3)
System.out.println("t1 "+i);
s.setState(1);
i = i +3 ;
s.notifyAll();
}
}
}
}
public class T2 implements Runnable {
State s;
public T2(State s) {
this.s =s;
}
#Override
public synchronized void run() {
int i =2;
while(i<50)
{
while(s.getState() != 1)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==1)
System.out.println("t2 "+i);
s.setState(2);
i = i +3 ;
s.notifyAll();
}
}
}
}
public class T3 implements Runnable {
State s;
public T3(State s) {
this.s =s;
}
#Override
public synchronized void run() {
int i =3;
while(i<50)
{
while(s.getState() != 2)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
if(s.getState()==2)
System.out.println("t3 "+i);
i = i +3 ;
s.setState(3);
s.notifyAll();
}
}
}}
public class T1t2t3 {
public static void main(String[] args) {
State s = new State();
Thread t1 = new Thread(new T1(s));
Thread t2 = new Thread(new T2(s));
Thread t3 = new Thread(new T3(s));
t1.start();
t2.start();
t3.start();
}
}
how can we ensure that thread T2 run after T1 and thread T3 run after T2?
NOTE: Assuming that it is not about scheduling the threads in the required order
We could use the Condition Interface.
We'll need two conditions bound to a single Lock: condition1 to coordinate T1 and T2, condition2 to coordinate T2 and T3.Pass condition1 to T1 and T2, condition2 to T2 and T3.
So, we would have T2 await on condition1 in it's run method, which will be signalled by T1 (from T1's run method, after T1 starts/finishes its task). Similarly have T3 await on condition2 in it's run method, which will be signalled by T2 (from T2's run method, after it starts/finishes it's task).
Create a priority queue with each tread in the other they are created.
You can then apply Thread.join after it completes, remove that thread from the priority queue, and then execute the first element of the queue again.
Pseudocode:
pthread [3] my_threads
my_queue
for t in pthreads:
my_queue.queue(t)
while !my_queue.empty()
pop the head of the queue
wait until it complets
thread.join()
implementation is left as exercise, so next time you get it right!
Use the thread isAlive method before starting the thread T2 and T3.
Thread t1 = new Thread(new T1());
Thread t2 = new Thread(new T2());
Thread t3 = new Thread(new T3());
t1.start();
if(t1.isAlive()){
t2.start();
}
if(t2.isAlive()){
t3.start();
}
Try the below code while using that you can run n number of thread in that manner.
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicExecutionOfThreads {
public static void main(String args[]) {
int totalNumOfThreads = 10;
PrintJob printJob = new PrintJob(totalNumOfThreads);
/*
MyRunnable runnable = new MyRunnable(printJob, 1);
Thread t1 = new Thread(runnable);
MyRunnable runnable2 = new MyRunnable(printJob, 2);
Thread t2 = new Thread(runnable2);
MyRunnable runnable3 = new MyRunnable(printJob, 3);
Thread t3 = new Thread(runnable3);
t1.start();
t2.start();
t3.start();
*/
//OR
ExecutorService executorService = Executors
.newFixedThreadPool(totalNumOfThreads);
Set<Runnable> runnables = new HashSet<Runnable>();
for (int i = 1; i <= totalNumOfThreads; i++) {
MyRunnable command = new MyRunnable(printJob, i);
runnables.add(command);
executorService.execute(command);
}
executorService.shutdown();
}
}
class MyRunnable implements Runnable {
PrintJob printJob;
int threadNum;
public MyRunnable(PrintJob job, int threadNum) {
this.printJob = job;
this.threadNum = threadNum;
}
#Override
public void run() {
while (true) {
synchronized (printJob) {
if (threadNum == printJob.counter) {
printJob.printStuff();
if (printJob.counter != printJob.totalNumOfThreads) {
printJob.counter++;
} else {
System.out.println();
// reset the counter
printJob.resetCounter();
}
printJob.notifyAll();
} else {
try {
printJob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class PrintJob {
int counter = 1;
int totalNumOfThreads;
PrintJob(int totalNumOfThreads) {
this.totalNumOfThreads = totalNumOfThreads;
}
public void printStuff() {
System.out.println("Thread " + Thread.currentThread().getName()
+ " is printing");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void resetCounter() {
this.counter = 1;
}
}
The concurrent package has better classes to use the shared object.
One of the way is like this.
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
ThreadId threadId = new RunInSequence.ThreadId();
threadId.setId(1);
Thread t1 = setThread("thread1",lock, condition, 1, 2, threadId);
Thread t2 = setThread("thread2",lock, condition, 2, 3, threadId);
Thread t3 = setThread("thread3",lock, condition, 3, 1, threadId);
t1.start();
t2.start();
t3.start();
}
private static class ThreadId {
private int id;
public ThreadId() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
private static Thread setThread(final String name,final Lock lock, final Condition condition, int actualThreadId, int nextThreadId,
ThreadId threadId) {
Thread thread = new Thread() {
#Override
public void run() {
while (true) {
lock.lock();
try {
while (threadId.getId() != actualThreadId) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+"prints: " + actualThreadId);
threadId.setId(nextThreadId);
condition.signalAll();
} finally {
lock.unlock();
}
}
}
};
return thread;
}
package thread;
class SyncPrinter {
public static void main(String[] args) {
SyncPrinterAction printAction1 = new SyncPrinterAction(new int[]{1,5,9,13}, true);
SyncPrinterAction printAction2 = new SyncPrinterAction(new int[]{2,6,10,14}, true);
SyncPrinterAction printAction3 = new SyncPrinterAction(new int[]{3,7,11,15}, true);
SyncPrinterAction printAction4 = new SyncPrinterAction(new int[]{4,8,12,16}, false);
printAction1.setDependentAction(printAction4);
printAction2.setDependentAction(printAction1);
printAction3.setDependentAction(printAction2);
printAction4.setDependentAction(printAction3);
new Thread(printAction1, "T1").start();;
new Thread(printAction2, "T2").start();
new Thread(printAction3, "T3").start();
new Thread(printAction4, "T4").start();
}
}
class SyncPrinterAction implements Runnable {
private volatile boolean dependent;
private SyncPrinterAction dependentAction;
int[] data;
public void setDependentAction(SyncPrinterAction dependentAction){
this.dependentAction = dependentAction;
}
public SyncPrinterAction( int[] data, boolean dependent) {
this.data = data;
this.dependent = dependent;
}
public SyncPrinterAction( int[] data, SyncPrinterAction dependentAction, boolean dependent) {
this.dependentAction = dependentAction;
this.data = data;
this.dependent = dependent;
}
#Override
public void run() {
synchronized (this) {
for (int value : data) {
try {
while(dependentAction.isDependent())
//System.out.println("\t\t"+Thread.currentThread().getName() + " :: Waithing for dependent action to complete");
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
dependentAction.setDependent(true);
System.out.println(Thread.currentThread().getName() + " :: " +value);
dependent = false;
}
}
}
private void setDependent(boolean dependent) {
this.dependent = dependent;
}
private boolean isDependent() {
return dependent;
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Worker implements Runnable {
BlockingQueue<Integer> q = new LinkedBlockingQueue<>();
Worker next = null; // next worker in the chain
public void setNext(Worker t) {
this.next = t;
}
public void accept(int i) {
q.add(i);
}
#Override
public void run() {
while (true) {
int i;
try {
i = q.take(); // this blocks the queue to fill-up
System.out.println(Thread.currentThread().getName() + i);
if (next != null) {
next.accept(i + 1); // Pass the next number to the next worker
}
Thread.sleep(500); // Just sleep to notice the printing.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PrintNumbersSequentially {
public static void main(String[] as) {
Worker w1 = new Worker();
Worker w2 = new Worker();
Worker w3 = new Worker();
w1.setNext(w2);
w2.setNext(w3);
w3.setNext(w1);
new Thread(w1, "Thread-1: ").start();
new Thread(w2, "Thread-2: ").start();
new Thread(w3, "Thread-3: ").start();
//Till here all the threads have started, but no action takes place as the queue is not filled for any worker. So Just filling up one worker.
w1.accept(100);
}
}
I think this could help you out.
By using join you can ensure running of a thread one after another.
class MyTestThread implements Runnable{
public void run() {
System.out.println("==MyTestThread : START : "+Thread.currentThread().getName());
for(int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName() + " :i = "+i);
}
System.out.println("==MyTestThread : END : "+Thread.currentThread().getName());
}
}
public class ThreadJoinTest {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new MyTestThread(), "t1");
Thread thread2 = new Thread(new MyTestThread(), "t2");
thread1.start();
thread1.join();
thread2.start();
thread2.join();
System.out.println("====All threads execution===completed");
}
}
package io.hariom.threading;
//You have three threads T1, T2, and T3, How do you ensure that they finish in order T1, T2, T3 ?
public class ThreadTest1 {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable(null));
Thread thread2 = new Thread(new MyRunnable(thread1));
Thread thread3 = new Thread(new MyRunnable(thread2));
thread1.start();
thread2.start();
thread3.start();
}
}
class MyRunnable implements Runnable {
Thread t;
MyRunnable(Thread t) {
this.t = t;
}
#Override
public void run() {
if (t != null) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " starts");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ends");
}
}
Here is my approach to the problem using CountDownLatch for signalling .
T1 thread after doing its job signal to T2 and T2 to T3.
public class T1T2T3 {
public static void main(String[] args) {
CountDownLatch c1 = new CountDownLatch(1);
CountDownLatch c2 = new CountDownLatch(1);
Thread T1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("T1");
c1.countDown();
}
});
Thread T2 = new Thread(new Runnable() {
#Override
public void run() {
//should listen to something from T1
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T2");
c2.countDown();
}
});
Thread T3 = new Thread(new Runnable() {
#Override
public void run() {
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T3");
}
});
T1.start();
T3.start();
T2.start();
}
}

Wait until child threads completed : Java

Problem description : -
Step 1: Take input FILE_NAME from user at main thread.
Step 2: Perform 10 operations on that file (i.e count chars, count lines etc.. ), and all those 10 operations must be in septate threads. It means there must be 10 child threads.
Step 3: Main thread waits until all those child threads completed.
Step 4: Print result.
What I did :-
I did a sample code with 3 threads. I don't want file operation code from your side.
public class ThreadTest {
// This is object to synchronize on.
private static final Object waitObject = ThreadTest.class;
// Your boolean.
private static boolean boolValue = false;
public final Result result = new Result();
public static void main(String[] args) {
final ThreadTest mytest = new ThreadTest();
System.out.println("main started");
new Thread(new Runnable() {
public void run() {
System.out.println("Inside thread");
//Int initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting integer value");
mytest.result.setIntValue(346635);
System.out.println("Integer value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//String initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting string value");
mytest.result.setStringValue("Hello hi");
System.out.println("String value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//Boolean initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting boolean value");
mytest.result.setBoolValue(true);
System.out.println("Boolean value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
System.out.println("Thread is finished");
//Notify to main thread
synchronized (ThreadTest.waitObject) {
ThreadTest.boolValue = true;
ThreadTest.waitObject.notifyAll();
}
}
}).start();
try {
synchronized (ThreadTest.waitObject) {
while (!ThreadTest.boolValue) {
ThreadTest.waitObject.wait();
}
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
}
Problem :-
My above code is not giving correct answer. How can I do that?
Alternate solutions:
CountDownLatch class does the same. But I don't want to use that class.
I looked this similar solution and I want to use methods of Thread only.
You can do:
Thread t = new Thread() {
public void run() {
System.out.println("text");
// other complex code
}
};
t.start();
t.join();
This way you will wait until the thread finishes and just then continue. You can join multiple threads:
for (Thread thread : threads) {
thread.join();
}
I would recommend looking at the Executors framework first, and then look into the CompletionService.
Then you can write something like this:
ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse);
CompletionService completion = new ExecutorCompletionService(executor);
for (each sub task) {
completion.submit(new SomeTaskYouCreate())
}
// wait for all tasks to complete.
for (int i = 0; i < numberOfSubTasks; ++i) {
completion.take(); // will block until the next sub task has completed.
}
executor.shutdown();
In Java 8 a far better approach is to use parallelStream()
Note: it is far easier to see exactly what these background tasks are doing.
public static void main(String[] args) {
Stream.<Runnable>of(
() -> mytest.result.setIntValue(346635),
() -> mytest.result.setStringValue("Hello hi"),
() -> mytest.result.setBoolValue(true) )
.parallel()
.forEach(Runnable::run);
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
I took out the debug information and the sleep as these don't alter the outcome.
You may want to choose CountDownLatch from java.util.concurrent. From JavaDocs:
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes.
Sample code:
import java.util.concurrent.CountDownLatch;
public class Test {
private final ChildThread[] children;
private final CountDownLatch latch;
public Test() {
this.children = new ChildThread[4];
this.latch = new CountDownLatch(children.length);
children[0] = new ChildThread(latch, "Task 1");
children[1] = new ChildThread(latch, "Task 2");
children[2] = new ChildThread(latch, "Task 3");
children[3] = new ChildThread(latch, "Task 4");
}
public void run() {
startChildThreads();
waitForChildThreadsToComplete();
}
private void startChildThreads() {
Thread[] threads = new Thread[children.length];
for (int i = 0; i < threads.length; i++) {
ChildThread child = children[i];
threads[i] = new Thread(child);
threads[i].start();
}
}
private void waitForChildThreadsToComplete() {
try {
latch.await();
System.out.println("All child threads have completed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ChildThread implements Runnable {
private final String name;
private final CountDownLatch latch;
protected ChildThread(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
#Override
public void run() {
try {
// Implementation
System.out.println(name + " has completed.");
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.run();
}
}
Output:
Task 1 has completed.
Task 4 has completed.
Task 3 has completed.
Task 2 has completed.
All child threads have completed.
There are many ways to approach this. Consider CountDownLatch:
import java.util.concurrent.CountDownLatch;
public class WorkerTest {
final int NUM_JOBS = 3;
final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS);
final Object mutex = new Object();
int workData = 0;
public static void main(String[] args) throws Exception {
WorkerTest workerTest = new WorkerTest();
workerTest.go();
workerTest.awaitAndReportData();
}
private void go() {
for (int i = 0; i < NUM_JOBS; i++) {
final int fI = i;
Thread t = new Thread() {
public void run() {
synchronized(mutex) {
workData++;
}
try {
Thread.sleep(fI * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
};
t.start();
}
}
private void awaitAndReportData() throws InterruptedException {
countDownLatch.await();
synchronized(mutex) {
System.out.println("All workers done. workData=" + workData);
}
}
}
Check if all child threads are dead, every n seconds. Simple, yet effective method:
boolean allDead=false;
while(! allDead){
allDead=true;
for (int t = 0; t < threadCount; t++)
if(threads[t].isAlive()) allDead=false;
Thread.sleep(2000);
}

Categories

Resources