Synchronize Three Threads - java

Was asked this question in an interview , tried to solve it ... but not successful.
I thought of using CyclicBarrier
There are three threads T1 prints 1,4,7... T2 prints 2,5,8... and T3 prints 3,6,9 …. How do you synchronize these three to print sequence 1,2,3,4,5,6,7,8,9....
I tried writing & running the following code
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cBarrier = new CyclicBarrier(3);
new Thread(new ThreadOne(cBarrier,1,10,"One")).start();
new Thread(new ThreadOne(cBarrier,2,10,"Two")).start();
new Thread(new ThreadOne(cBarrier,3,10,"Three")).start();
}
}
class ThreadOne implements Runnable {
private CyclicBarrier cb;
private String name;
private int startCounter;
private int numOfPrints;
public ThreadOne(CyclicBarrier cb, int startCounter,int numOfPrints,String name) {
this.cb = cb;
this.startCounter=startCounter;
this.numOfPrints=numOfPrints;
this.name=name;
}
#Override
public void run() {
for(int counter=0;counter<numOfPrints;counter++)
{
try {
// System.out.println(">>"+name+"<< "+cb.await());
cb.await();
System.out.println("["+name+"] "+startCounter);
cb.await();
//System.out.println("<<"+name+">> "+cb.await());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
startCounter+=3;
}
}
}
output
[Three] 3
[One] 1
[Two] 2
[One] 4
[Two] 5
[Three] 6
[Two] 8
[One] 7
[Three] 9
[One] 10
[Two] 11
[Three] 12
[Two] 14
[One] 13
[Three] 15
[One] 16
[Two] 17
[Three] 18
[Two] 20
[One] 19
[Three] 21
[One] 22
[Two] 23
[Three] 24
[Two] 26
[One] 25
[Three] 27
[One] 28
[Two] 29
[Three] 30
Can anyone help me with correct ans ?
Similar Ques
Thread Synchronization - Synchronizing three threads to print 012012012012..... not working

As the others already mentioned, CyclicBarrier is not exactly the best tool for the task.
I also share the opinion that the solution is to chain the threads and let always one thread set the go for the next one.
Here goes an implementation using Semaphore:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Semaphore;
public class PrintNumbersWithSemaphore implements Runnable {
private final Semaphore previous;
private final Semaphore next;
private final int[] numbers;
public PrintNumbersWithSemaphore(Semaphore previous, Semaphore next, int[] numbers) {
this.previous = previous;
this.next = next;
this.numbers = numbers;
}
#Override
public void run() {
for (int i = 0; i < numbers.length; i++) {
wait4Green();
System.out.println(numbers[i]);
switchGreen4Next();
}
}
private void switchGreen4Next() {
next.release();
}
private void wait4Green() {
try {
previous.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(1);
Semaphore sem3 = new Semaphore(1);
sem1.acquire();
sem2.acquire();
sem3.acquire();
Thread t1 = new Thread(new PrintNumbersWithSemaphore(sem3, sem1, new int[] { 1, 4, 7 }));
Thread t2 = new Thread(new PrintNumbersWithSemaphore(sem1, sem2, new int[] { 2, 5, 8 }));
Thread t3 = new Thread(new PrintNumbersWithSemaphore(sem2, sem3, new int[] { 3, 6, 9 }));
t1.start();
t2.start();
t3.start();
sem3.release();
t1.join();
t2.join();
t3.join();
}
}
Here goes another one, in my opinion quite cumbersome implementation using CyclicBarrier:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class PrintNumbersWithCyclicBarrier implements Runnable {
private final CyclicBarrier previous;
private final CyclicBarrier next;
private final int[] numbers;
public PrintNumbersWithCyclicBarrier(CyclicBarrier previous, CyclicBarrier next, int[] numbers) {
this.previous = previous;
this.next = next;
this.numbers = numbers;
}
#Override
public void run() {
for (int i = 0; i < numbers.length; i++) {
wait4Green();
System.out.println(numbers[i]);
switchRed4Myself();
switchGreen4Next();
}
}
private void switchGreen4Next() {
try {
next.await();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private void switchRed4Myself() {
previous.reset();
}
private void wait4Green() {
try {
previous.await();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
CyclicBarrier cb1 = new CyclicBarrier(2);
CyclicBarrier cb2 = new CyclicBarrier(2);
CyclicBarrier cb3 = new CyclicBarrier(2);
Thread t1 = new Thread(new PrintNumbersWithCyclicBarrier(cb3, cb1, new int[] { 1, 4, 7 }));
Thread t2 = new Thread(new PrintNumbersWithCyclicBarrier(cb1, cb2, new int[] { 2, 5, 8 }));
Thread t3 = new Thread(new PrintNumbersWithCyclicBarrier(cb2, cb3, new int[] { 3, 6, 9 }));
t1.start();
t2.start();
t3.start();
cb3.await();
t1.join();
t2.join();
t3.join();
}
}

Was the requirement to use a single CyclicBarrier? My suggestion is:
For each ThreadOne instance assign two CyclicBarriers
You should create a cyclic graph such that
ThreadOne_1 -> ThreadOne_2 -> ThreadOne_3 -> ThreadOne_1 -> etc...
To achieve (2) you would need to share the parent's CyclicBarrier with the child's and than the last task should share it's CB with the first Thread's child.
To answer your questions:
Tried going through the documents , but not very clear what exactly does await() do ...
Await will suspend itself until N number of threads have invoked await on the barrier. So if you define new CyclicBarrier(3) than once 3 threads invoke await the barrier will allow threads to continue.
When to use reset()
You don't need to, it will auto trip the barrier once the number of threads arive

Here is a way of doing it which works for an arbitrary number of threads using synchronized, wait and notifyAll.
A turn variable controls which is the thread that has to execute. Such thread executes the task, increases turn (in modulo number of threads), notifeis all threads and goes to a while loop awaiting until it is its turn again.
public class Test2 {
final static int LOOPS = 10;
final static int NUM_TREADS = 3;
static class Sequenced extends Thread {
static int turn = 0;
static int count = 0;
static Object lock = new Object();
final int order;
public Sequenced(int order) {
this.order = order;
}
#Override
public void run() {
synchronized (lock) {
try {
for (int n = 0; n < LOOPS; ++n) {
while (turn != order) {
lock.wait();
}
++count;
System.out.println("T" + (order + 1) + " " + count);
turn = (turn + 1) % NUM_TREADS;
lock.notifyAll();
}
} catch (InterruptedException ex) {
// Nothing to do but to let the thread die.
}
}
}
}
public static void main(String args[]) throws InterruptedException {
Sequenced[] threads = new Sequenced[NUM_TREADS];
for (int n = 0; n < NUM_TREADS; ++n) {
threads[n] = new Sequenced(n);
threads[n].start();
}
for (int n = 0; n < NUM_TREADS; ++n) {
threads[n].join();
}
}
}

As threads should be given equal weightage i.e first after second after third. The following works.
public class MultiThreadSynchronize {
static int index = 0;
static Object lock = new Object();
static class NumberPrinter extends Thread {
private final int remainder;
private final int noOfThreads;
private int value;
public NumberPrinter(String name, int remainder, int noOfThreads, int value) {
super(name);
this.remainder = remainder;
this.noOfThreads = noOfThreads;
this.value = value;
}
#Override
public void run() {
while (index < 20) {
synchronized (lock) {
while ((index % noOfThreads) != remainder) {. // base condition where all threads except one waits.
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
index++;
System.out.println(getName() + " " + value);
value += 3;
lock.notifyAll();
}
}
}
}
public static void main(String[] args) {
NumberPrinter numberPrinter1 = new NumberPrinter("First Thread", 0, 3, 1);
NumberPrinter numberPrinter2 = new NumberPrinter("Second Thread", 1, 3, 2);
NumberPrinter numberPrinter3 = new NumberPrinter("Third Thread", 2, 3, 3);
numberPrinter1.start(); numberPrinter2.start(); numberPrinter3.start();
}
}

I have coded one three thread application using events
#include <iostream>
#include <Windows.h>
#include <atomic>
using namespace std;
HANDLE firstThreadEvent = CreateEvent(NULL, true, true, NULL);
HANDLE secondThreadEvent = CreateEvent(NULL, true, false, NULL);
HANDLE thirdThreadEvent = CreateEvent(NULL, true, false, NULL);
std::atomic<int> m_int = 1;
DWORD WINAPI firstThreadFun(LPVOID lparam)
{
while (1)
{
::WaitForSingleObject(firstThreadEvent,INFINITE);
cout << "By first thread " << m_int << std::endl;
m_int++;
ResetEvent(firstThreadEvent);
SetEvent(secondThreadEvent);
}
}
DWORD WINAPI secondThreadFun(LPVOID lparam)
{
while (1)
{
::WaitForSingleObject(secondThreadEvent, INFINITE);
cout << "By second thread "<< m_int << std::endl;
m_int++;
ResetEvent(secondThreadEvent);
SetEvent(thirdThreadEvent);
}
}
DWORD WINAPI thirdThreadFun(LPVOID lparam)
{
while (1)
{
::WaitForSingleObject(thirdThreadEvent, INFINITE);
cout << "By third thread " << m_int << std::endl;
m_int++;
ResetEvent(thirdThreadEvent);
SetEvent(firstThreadEvent);
}
}
int main()
{
HANDLE hnd[3];
hnd[0] = CreateThread(NULL, 0, &firstThreadFun, NULL, 0, NULL);
hnd[1] = CreateThread(NULL, 0, &secondThreadFun, NULL, 0, NULL);
hnd[2] = CreateThread(NULL, 0, &thirdThreadFun, NULL, 0, NULL);
WaitForMultipleObjects(3, hnd, true, INFINITE);
CloseHandle(hnd[0]);
CloseHandle(hnd[1]);
CloseHandle(hnd[2]);
return 0;
}

Related

Interchangeable role of producer consumer threads in Java Multithreaded Program

Objective : To create two threads such that producer and consumer threads work interchangeably i.e if first thread acts as producer than second act as consumer and vice versa.
Details : They communicate with each other through a buffer,Storing one integer size. For example if first thread produces 1 then second thread consumes it and produces 2 and then the first thread consumes 2 and produces next three integers and Consumer consumes them one by one.
Both threads terminate after that.
Also both threads should be able to initiate the communication.
I tried to write the following code.
import java.util.Random;
class CommonItem {
boolean flag = false;
int arr[];
public synchronized void Send(String msg) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void Receive(String msg) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
arr = send_random();
for (int item: arr) {
System.out.println(item);
}
flag = false;
notify();
}
synchronized int[] send_random(){
int[] arr = new int[3];
Random random= new Random();
for (int i = 0; i < 3; i++) {
arr[i]=random.nextInt(100);
}
return arr;
}
}
class T1 implements Runnable {
CommonItem Ci;
public T1(CommonItem Ci) {
this.Ci = Ci;
new Thread(this, "producer").start();
}
public void run() {
while (true)
Ci.Send("sent :1");
}
}
class T2 implements Runnable {
CommonItem Ci;
public T2(CommonItem m2) {
this.Ci = m2;
new Thread(this, "Consumer").start();
}
public void run() {
while (true)
Ci.Receive("received :2");
}
}
public class TestClass {
public static void main(String[] args) {
CommonItem m = new CommonItem();
new T1(m);
new T2(m);
}
}
The expected output is
sent :1
received :1
sent :2
received :2
sent :57 4 13
received :57 4 13
But I get the following output
OUTPUT
sent :1
received :2
57
4
13
Please suggest if any correction in the code or any idea on how to solve the given problem in an alternate way. Thank you in advance.
public class CommonItem {
boolean receiver = false;
List<Integer> list = new ArrayList<>();
public void receive() throws InterruptedException {
String name = Thread.currentThread().getName();
synchronized (list) {
while (list.isEmpty()) {
list.notify();
list.wait();
}
// Receive all elements
System.out.printf("Receiving elements by %s:\t", name);
for (int val : list) {
System.out.print(val + " ");
}
list.clear();
System.out.println();
list.notify();
list.wait();
}
}
public void send() throws InterruptedException {
String name = Thread.currentThread().getName();
synchronized (list) {
while (!list.isEmpty()) {
list.notify();
list.wait();
}
// Sending elements
int[] arr = get_random();
System.out.printf("Sending elements by %s\t", name);
for (int ele : arr) {
list.add(ele);
System.out.print(ele + " ");
}
System.out.println();
list.notify();
list.wait();
}
}
public int[] get_random() throws InterruptedException {
int[] arr = new int[3];
Random random = new Random();
for (int i = 0; i < 3; i++) {
arr[i] = random.nextInt(100);
}
Thread.sleep(1000);
return arr;
}
}
public class ThreadTask implements Runnable {
private CommonItem item;
private boolean receiver;
public ThreadTask(CommonItem item, boolean receiver) {
this.item = item;
this.receiver = receiver;
}
public static void main(String[] args) {
CommonItem item = new CommonItem();
Thread t1 = new Thread(new ThreadTask(item, false), "First");
Thread t2 = new Thread(new ThreadTask(item, true), "Second");
t1.start();
t2.start();
}
#Override
public void run() {
while (true) {
try {
if (receiver) {
item.receive();
} else {
item.send();
}
receiver = !receiver;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Sending elements by First 25 6 57
Receiving elements by Second: 25 6 57
Sending elements by Second 35 99 10
Receiving elements by First: 35 99 10
Sending elements by First 84 11 1
Receiving elements by Second: 84 11 1
Sending elements by Second 68 91 53
Receiving elements by First: 68 91 53
package java11;
import java.util.*;
import java.util.Random;
class CommonItem
{
boolean receiver = false;
List<Integer> list = new ArrayList<>();
int k=1;
public void receive() throws InterruptedException
{
String name = Thread.currentThread().getName();
synchronized (list)
{
while (list.isEmpty())
{
list.notify();
list.wait();
}
// Receive all elements
System.out.printf("Receiving elements by %s:\t", name);
for (int val : list)
{
System.out.print(val + " ");
}
list.clear();
System.out.println();
list.notify();
list.wait();
}
}
public void send(int i) throws InterruptedException
{
String name = Thread.currentThread().getName();
synchronized (list)
{
while (!list.isEmpty())
{
list.notify();
list.wait();
}
// Sending elements
int[] arr;
if(i<3)
{
arr = get_random(k);
k++;
}
else
{
arr = get_random1();
}
System.out.printf("Sending elements by %s\t", name);
for (int ele : arr)
{
list.add(ele);
System.out.print(ele + " ");
}
System.out.println();
list.notify();
list.wait();
}
}
public int[] get_random(int k) throws InterruptedException
{
int[] arr = new int[1];
arr[0] = k;
Thread.sleep(1000);
return arr;
}
public int[] get_random1() throws InterruptedException
{
int[] arr = new int[3];
Random random = new Random();
for (int i = 0; i < 3; i++)
{
arr[i] = random.nextInt(100);
}
Thread.sleep(1000);
return arr;
}
}
public class Java11 implements Runnable
{
private CommonItem item;
private boolean receiver;
public Java11(CommonItem item, boolean receiver)
{
this.item = item;
this.receiver = receiver;
}
public static void main(String[] args)
{
int choice;
CommonItem item = new CommonItem();
System.out.println("Who should start first?:Thread 1 or Thread 2");
Scanner sc=new Scanner(System.in);
choice=sc.nextInt();
if(choice==1)
{
Thread t1 = new Thread(new Java11(item, false), "First");
Thread t2 = new Thread(new Java11(item, true), "Second");
t1.start();
t2.start();
}
else if(choice==2)
{
Thread t1 = new Thread(new Java11(item, true), "First");
Thread t2 = new Thread(new Java11(item, false), "Second");
t1.start();
t2.start();
}
}
#Override
public void run()
{
int i=1;
while (i<=3)
{
try
{
if (receiver)
{
item.receive();
}
else
{
item.send(i);
}
receiver = !receiver;
}
catch(InterruptedException e)
{
e.printStackTrace();
}
i++;
}
}
}
Slight changes are made in Sanit's code to get exact output as demanded by the problem statement.
OUTPUT:
Who should start first?:Thread 1 or Thread 2
1
Sending elements by First 1
Receiving elements by Second: 1
Sending elements by Second 2
Receiving elements by First: 2
Sending elements by First 90 95 28
Receiving elements by Second: 90 95 28
Who should start first?:Thread 1 or Thread 2
2
Sending elements by Second 1
Receiving elements by First: 1
Sending elements by First 2
Receiving elements by Second: 2
Sending elements by Second 42 10 33
Receiving elements by First: 42 10 33
Thank you #Sanit.
Solved- #Kunjan Rana

Java - print sequence of numbers using two threads with inter thread communication

I want to print number in the below format. This should be taken care by two thread t1,t2. Can anyone help to enhance the below code which I have written?
First t1 should print 0-4
Then t2 should print 5-9
Then again t1 should print 10-14
Then t2 should print 15-19
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PrintNumber implements Runnable{
String name;
public void run(){
print();
}
synchronized public void print(){
for(int i=0;i< 5;i++){
System.out.println(i+" -- "+Thread.currentThread());
}
}
public static void main(String[] args){
Runnable r = new PrintNumber();
Thread t1 = new Thread(r,"t1");
Thread t2 = new Thread(r,"t2");
t1.start();
t2.start();
}
}
Instead of using the low-level wait() and notify() you can use two Sempaphores.
Each Runnable has a Semaphore it waits for and one it uses to notify the next one.
import java.util.concurrent.Semaphore;
class PrintNumber implements Runnable{
static volatile int nextStartIdx;
private Semaphore waitForSemaphore;
private Semaphore next;
public PrintNumber(Semaphore waitFor, Semaphore next) {
this.waitForSemaphore = waitFor;
this.next = next;
}
public void run(){
while (true) {
print();
}
}
public void print() {
try {
waitForSemaphore.acquire();
int start = nextStartIdx;
for(int i=0;i< 5;i++){
System.out.println(String.format("%d -- %s", i + start, Thread.currentThread().getName()));
}
nextStartIdx += 5;
next.release();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args){
Semaphore a = new Semaphore(1);
Semaphore b = new Semaphore(0);
Thread t1 = new Thread(new PrintNumber(a,b),"t1");
Thread t2 = new Thread(new PrintNumber(b,a),"t2");
t1.start();
t2.start();
}
}
You can use wait and notify to achieve inter thread communication for your sczenario.
class PrintNumber implements Runnable {
String name;
Integer count = 0;
#Override
public void run() {
try {
print();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void print() throws InterruptedException {
while (count < 15) {
for (int i = 0; i < 5; i++) {
count++;
System.out.println(count + " -- " + Thread.currentThread());
}
notifyAll();
wait();
}
}
public static void main(final String[] args) {
final Runnable r = new PrintNumber();
final Thread t1 = new Thread(r, "t1");
final Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
For more information see:
A simple scenario using wait() and notify() in java

Printing values from different threads using wait and notify

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

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

3 threads to print alternate values in sequence

I am trying to create an implementation where multiple threads print alternate values of sequence. So here thread1 will print 1,4,7 thread2 will print 2,5,8 thread3 will print 3,6,9. I am using Atomic integer and modulo function.
Below implementation works fine in the sense that first thread prints 1,4,7 while second prints 2,5,8 and third prints 3,6,9 but problem is that sequence is not maintained i.e output can be like 1,3,2,4,5,7,8,6,9 while i want sequence to be maintained as proper threads shld print those values.
One condition is i don't want to use synchronize. [Just for learning purpose]
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadsOrderedLockLess {
AtomicInteger sharedOutput = new AtomicInteger(0);
public static void main(String args[]) {
ThreeThreadsOrderedLockLess t = new ThreeThreadsOrderedLockLess();
ThreadTasks t1 = t.new ThreadTasks(0);
ThreadTasks t2 = t.new ThreadTasks(1);
ThreadTasks t3 = t.new ThreadTasks(2);
Thread ts1 = new Thread(t1);
Thread ts2 = new Thread(t2);
Thread ts3 = new Thread(t3);
ts1.start();
ts2.start();
ts3.start();
}
private class ThreadTasks implements Runnable {
private final int threadPosition;
public ThreadTasks(int threadPosition) {
super();
this.threadPosition = threadPosition;
}
#Override
public void run() {
while (sharedOutput.get() < 9) {
if (sharedOutput.get() % 3 == this.threadPosition) {
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ sharedOutput.incrementAndGet());
}
}
}
}
}
You should print first, and increment after:
int value = sharedOutput.get() + 1;
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ value);
sharedOutput.incrementAndGet();
That said, all the threads are busy looping, which will lead to 100% CPU usage. You should synchronize the threads instead.
Below code snippet will print numbers in sequence and all threads will be terminated gracefully after the task.
Used AtomicInteger, which is thread-safe for printing the numbers and same logic can be applied to print as till any number with any number of threads.
import java.util.concurrent.atomic.AtomicInteger;
public class PrintNumSequence
{
public static void main(String[] args)
{
AtomicInteger atomicInteger = new AtomicInteger(0);
new NumPrinter(atomicInteger, 0).start();// thread0
new NumPrinter(atomicInteger, 1).start();// thread1
new NumPrinter(atomicInteger, 2).start();// thread2
}
}
class NumPrinter extends Thread
{
private AtomicInteger atomicInteger;
private int threadNum;
public NumPrinter(AtomicInteger atomicInteger, int threadNum)
{
this.atomicInteger = atomicInteger;
this.threadNum = threadNum;
}
#Override
public void run()
{
int num = atomicInteger.intValue();
do
{
synchronized (atomicInteger)
{
num = atomicInteger.intValue();
// If number is 9 then stop.
if (num > 9)
{
atomicInteger.notifyAll();
break;
}
// 3 is number of threads
if ((num % 3) == threadNum)
{
System.out.println("Thread-" + threadNum + " -->" + num);
num = atomicInteger.incrementAndGet();
}
atomicInteger.notifyAll();
try
{
atomicInteger.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} while (true);
}
}
This is because the time slice for each thread is determined by the OS. So it is possible that thread x increments the shared number but before printing the time slice is passed to the next thread y which now reads the shared number and prints it after incrementing (assuming that thread y got more time than thread x to increament and print the shared number)
.
use wait(), notify(), notifyall() methods of the Java.
you can also take a look at this Tutorial of these methods.
Hope this would be helpful to solve your issue. . .
the output of this example is as under.
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
This should work:
package com.sid;
import java.util.concurrent.atomic.AtomicInteger;
public class NumberSequence {
private AtomicInteger sharedOutput = new AtomicInteger(0);
private Object object = new Object();
public static void main(String args[]) {
NumberSequence t = new NumberSequence();
ThreadTasks t1 = t.new ThreadTasks(0);
ThreadTasks t2 = t.new ThreadTasks(1);
ThreadTasks t3 = t.new ThreadTasks(2);
Thread ts1 = new Thread(t1);
Thread ts2 = new Thread(t2);
Thread ts3 = new Thread(t3);
ts1.start();
ts2.start();
ts3.start();
}
private class ThreadTasks implements Runnable {
private final int threadPosition;
public ThreadTasks(int threadPosition) {
super();
this.threadPosition = threadPosition;
}
#Override
public void run() {
while (sharedOutput.get() < 10) {
synchronized (object) {
if (sharedOutput.get() % 3 == this.threadPosition) {
if(sharedOutput.get() < 10)
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ sharedOutput.incrementAndGet());
}
}
}
}
}
}
Proper synchronization would help you get the clear answer. I've improved the implementation, you should solve your questions.
int threadId;
int moduluos;
int numOfThreads;
public ThreadTasks(int id, int nubOfThreads) {
threadId = id;
this.numOfThreads = nubOfThreads;
moduluos = threadId%numOfThreads;
}
public void run() {
print();
}
private void print() {
try {
while (true) {
synchronized (monitor) {
if (number.get() % numOfThreads != moduluos) {
monitor.wait();
} else {
System.out.println("ThreadId [" + threadId
+ "] printing -->"
+ number.getAndIncrement());
monitor.notifyAll();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package test.mk.thread;
import java.util.concurrent.atomic.AtomicInteger;
public class MkThread2 {
int nextThreadToRun = 1;
int[] arr = {1,2,3,4,5,6,7,8,9,10,11};
AtomicInteger nextArrayIndex = new AtomicInteger(0);
boolean token = true;
public static void main(String[] args) {
MkThread2 mkThread = new MkThread2();
Thread t1 = new Thread(new Worker2(1, mkThread));
Thread t2 = new Thread(new Worker2(2, mkThread));
Thread t3 = new Thread(new Worker2(3, mkThread));
t1.start();
t2.start();
t3.start();
}
}
class Worker2 implements Runnable{
volatile int threadNo;
private MkThread2 mkThread;
private String threadName;
Worker2(int threadNo, MkThread2 mkThread){
this.threadNo = threadNo;
this.mkThread = mkThread;
this.threadName = "Thread:"+threadNo ;
}
public void run(){
try{
synchronized (mkThread) {
while(mkThread.token){
while(threadNo != mkThread.nextThreadToRun){
mkThread.wait();
}
if(mkThread.token){//double checking
System.out.print(threadName+ "->" + mkThread.arr[mkThread.nextArrayIndex.get()]);
if(threadNo == 3) System.out.println();
mkThread.nextThreadToRun = getNextThread(threadNo);
if(mkThread.nextArrayIndex.get() == mkThread.arr.length-1){
mkThread.token = false;
}
mkThread.nextArrayIndex.incrementAndGet();
}
mkThread.notifyAll();
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
private int getNextThread(int threadNo){
int result = -1;
switch (threadNo) {
case (1):
result = 2;
break;
case (2):
result = 3;
break;
case (3):
result = 1;
break;
}
return result;
}
}
import java.util.concurrent.atomic.AtomicInteger;
public class Print123456789 {
public static void main(String[] args) {
print p1 = new print(0);
print p2 = new print(1);
print p3 = new print(2);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p2);
Thread t3 = new Thread(p3);
t1.start();
t2.start();t3.start();
}
}
class print implements Runnable {
private int threadNumber;
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public print(int threadNumber) {
super();
this.threadNumber = threadNumber;
}
public void run(){
try{
while(atomicInteger.get() < 10){
synchronized (atomicInteger) {
if((atomicInteger.get()%3) == this.threadNumber){
System.out.println(atomicInteger.getAndIncrement() + " Thread :" + this.threadNumber );
atomicInteger.notifyAll();
}
else
atomicInteger.wait();
}
}
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
This can be better implemented using blocking queues. Define a worker holding a blocking queue. The workers waits on the queue until it receives a number in it. It prints the number it receives, increments it and passes it on to the next worker in the chain. Refer here for the full solution.
package threeThread;
class Task implements Runnable {
String message;
ThreeThread lock;
int i = 0;
int p;
public Task(String text, ThreeThread obj, int p) {
message = text;
this.lock = obj;
this.p = p;
}
#Override
public void run() {
while(true) {
synchronized (lock) {
while(!((lock.status % 3) == 0) && p == 1){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while(!((lock.status % 3) == 1) && p == 2){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while(!((lock.status % 3) == 2) && p == 3){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("thread: " + p + " : " + message);
lock.status++;
lock.notifyAll();
}
}
}
}
public class ThreeThread {
volatile int status = 0;
public static void main(String[] args) {
ThreeThread lock = new ThreeThread();
Thread t1 = new Thread(new Task("Hello", lock,1));
Thread t2 = new Thread(new Task("Good", lock,2));
Thread t3 = new Thread(new Task("Morning", lock,3));
t1.start();
t2.start();
t3.start();
}
}
I am putting code to print 1-100 using 5 threads. One can use any number of thread to print output in round robin fashion.
Basic concept is to lock one object and notify other for executing the printing of value.
public class PrintOneToHundredUsing5Threads {
public static void main(String[] args) {
List<Object> objList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
objList.add(new Object());
}
for (int i = 0; i < 5; i++) {
Thread t = new Thread(new PrintThread(objList.get(i), objList.get((i + 1) % 5)));
t.setName("Thread" + i);
t.start();
}
}
}
class PrintThread implements Runnable {
Object current;
Object next;
volatile static int i = 1;
PrintThread(Object cur, Object next) {
this.current = cur;
this.next = next;
}
#Override
public void run() {
for (; i <= 100;) {
synchronized (current) {
synchronized (next) {
next.notify();
System.out.println(Thread.currentThread().getName() + " Value : " + i++);
}
try {
current.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
You can use below code to print sequential numbers using multiple threads -
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ThreadCall extends Thread {
private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
private ThreadCall next;
public void setNext(ThreadCall t) {
this.next = t;
}
public void addElBQ(int a) {
this.bq.add(a);
}
public ThreadCall(String name) {
this.setName(name);
}
#Override
public void run() {
int x = 0;
while(true) {
try {
x = 0;
x = bq.take();
if (x!=0) {
System.out.println(Thread.currentThread().getName() + " =>" + x);
if (x >= 100) System.exit(0); // Need to stop all running threads
next.addElBQ(x+1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int THREAD_COUNT = 10;
List<ThreadCall> listThread = new ArrayList<>();
for (int i=1; i<=THREAD_COUNT; i++) {
listThread.add(new ThreadCall("Thread " + i));
}
for (int i = 0; i < listThread.size(); i++) {
if (i == listThread.size()-1) {
listThread.get(i).setNext(listThread.get(0));
}
else listThread.get(i).setNext(listThread.get(i+1));
}
listThread.get(0).addElBQ(1);
for (int i = 0; i < listThread.size(); i++) {
listThread.get(i).start();
}
}
}
Hope this will resolve your problem.
public class PrintThreadsInSerial {
public static void main(String[] args) {
Thread t = new Thread(new Job());
t.start();
}
}
class Job implements Runnable {
#Override
public void run() {
while (true) {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
}
}
}
}
The ThreadSynchronization class can be used to print numbers between 'n' no. of threads in sequence.
The logic is to create a common object between each of the consecutive threads and use 'wait', 'notify' to print the numbers in sequence.
Note: Last thread will share an object with the first thread.
You can change the 'maxThreads' value to increase or decrease the number of thread in the program before running it.
import java.util.ArrayList;
import java.util.List;
public class ThreadSynchronization {
public static int i = 1;
public static final int maxThreads = 10;
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < maxThreads; i++) {
list.add(new Object());
}
Object currObject = list.get(maxThreads - 1);
for (int i = 0; i < maxThreads; i++) {
Object nextObject = list.get(i);
RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
Thread th = new Thread(a);
th.setName("Thread - " + (i + 1));
th.start();
currObject = list.get(i);
}
}
}
class RunnableClass implements Runnable {
private Object currObject;
private Object nextObject;
private boolean firstThread;
public RunnableClass(Object currObject, Object nextObject, boolean first) {
this.currObject = currObject;
this.nextObject = nextObject;
this.firstThread = first;
}
#Override
public void run() {
int i = 0;
try {
if (firstThread) {
Thread.sleep(5000);
firstThread = false;
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
synchronized (nextObject) {
nextObject.notify();
}
}
while (i++ < Integer.MAX_VALUE) {
synchronized (currObject) {
currObject.wait();
}
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
Thread.sleep(1000);
synchronized (nextObject) {
nextObject.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class PrintSeqNumUsingAltThreads {
public static void main(String[] args) {
AtomicInteger counter = new AtomicInteger(0);
int numThreads = 3;
Thread t1 = new Thread(new SeqNumPrinter(counter, 0, numThreads));
Thread t2 = new Thread(new SeqNumPrinter(counter, 1, numThreads));
Thread t3 = new Thread(new SeqNumPrinter(counter, 2, numThreads));
t1.currentThread().setName("T1");
t2.currentThread().setName("T2");
t3.currentThread().setName("T3");
t1.start();
t2.start();
t3.start();
}
}
public class SeqNumPrinter implements Runnable {
AtomicInteger atmCounter;
Integer threadPosition;
Integer numThreads;
public SeqNumPrinter(AtomicInteger counter, int position, int numThreads) {
this.atmCounter = counter;
this.threadPosition = position;
this.numThreads = numThreads;
}
#Override
public void run() {
while (atmCounter.get() < 10) {
if (atmCounter.get() % numThreads == threadPosition) {
System.out.println("Printing value : " + atmCounter.getAndIncrement() + ", by thread : " +
Thread.currentThread().getName());
}
}
}
}
Output :
Printing value : 0, by thread : Thread-0 Printing value : 1, by
thread : Thread-1 Printing value : 3, by thread : Thread-0
Printing value : 2, by thread : Thread-2 Printing value : 4, by
thread : Thread-1 Printing value : 6, by thread : Thread-0
Printing value : 5, by thread : Thread-2 Printing value : 7, by
thread : Thread-1 Printing value : 9, by thread : Thread-0
Printing value : 8, by thread : Thread-2

Categories

Resources