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
Related
So i need to process a couple data files using threads (already splitted), and i'm having issues on how to stop the main thread till all the subthreads finish.
i looked around and tried to use join() but this causes an issue:
If i join the main thread with the last thread then since the other threads run at the same time, the last thread is not always the last one to finish
If i join the main thread with all the other threads then they don't run at the same time, the second needs the first to finish first.
also tried wait() and notify() but had even more issues. here's a part of my code
public class Matrix extends MapReduce {
ArrayList<String> VecteurLines = new ArrayList<String>();
protected int[] nbrLnCol = {0,0};
protected static double[] res;
public Matrix(String n) {
super(n);
}
public Matrix(String n,String m){
super(n,m);
}
public void Reduce() throws IOException, InterruptedException, MatrixException {
for (int i = 1; i <= Chunks; i++) {
Thread t=new Thread(new RunThread(VecteurLines,i,this));
t.start();
}
}
And here's the class that handles the threads
public class RunThread extends Matrix implements Runnable {
Matrix ma;
ArrayList<String> vec;
int threadNbr;
public RunThread(ArrayList<String> vec, int threadNbr,Matrix ma) {
super("","");
this.vec=vec;this.threadNbr=threadNbr;this.ma=ma; }
#Override
public void run() {
FileInputStream fin = null;
try {
fin = new FileInputStream(ma.getNom()+threadNbr+".txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Scanner sc = new Scanner(fin);
while (sc.hasNext()) {
String nextString = sc.next();
ma.nbrLnCol[0]++;
String [] arr = nextString.split(",");
ma.nbrLnCol[1]=arr.length;
double c=0;
for(int j=0;j<arr.length;j++)
{
c+=(Double.parseDouble(arr[j])*Double.parseDouble(vec.get(j)));
}
res[threadNbr-1]=c;
}
sc.close();
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
File file = new File(ma.getNom()+threadNbr+".txt");
file.delete();
}
Try like this:
private List<Thread> threadList = new ArrayList<>();
public void Reduce() {
threadList.clear();
for (int i = 1; i <= Chunks; i++) {
Thread t =new Thread(new RunThread(VecteurLines,i,this));
threadList.add(t);
}
// start all worker threads
for(int i=0; i<threadList.size(); i++){
threadList.get(i).start();
}
// wait until all worker threads is finished
while (true) {
int threadIsNotLive = 0;
for (int i = 0; i < threadList.size(); i++) {
Thread t = threadList.get(i);
if (!t.isAlive() || t == null) {
++threadIsNotLive;
}
}
if(threadIsNotLive>0 && (threadList.size() == threadIsNotLive)){
break;
// all worker threads is finished
}
else {
Thread.sleep(50);
// wait until all worker threads is finished
}
}
}
OR
public void Reduce() {
List<Thread> threadList = new ArrayList<>();
for (int i = 1; i <= Chunks; i++) {
Thread t =new Thread(new RunThread(VecteurLines,i,this));
threadList.add(t);
}
// start all worker threads
for(int i=0; i<threadList.size(); i++){
threadList.get(i).start();
threadList.get(i).join();
}
}
I believe you need two points in your code:
Your main thread has to end last after all the thread's executed because you said
"how to stop the main thread till all the subthreads finish"
.
Second ,the thread should finish one after another that is the 2nd thread should finish after 1st thread as you said
"the second needs the first to finish first."
Here is my code to do it with join .
public class Matrix extends MapReduce {
ArrayList<String> VecteurLines = new ArrayList<String>();
protected int[] nbrLnCol = {0,0};
protected static double[] res;
public Matrix(String n) {
super(n);
}
public Matrix(String n,String m){
super(n,m);
}
public void Reduce() throws IOException, InterruptedException, MatrixException {
Thread t = null;
for (int i = 1; i <= Chunks; i++) {
Thread t=new Thread(new RunThread(t,VecteurLines,i,this));
t.start();
}
t.join(); // finally main thread joining with the last thread.
}
and
public class RunThread extends Matrix implements Runnable {
Matrix ma;
ArrayList<String> vec;
int threadNbr;
Thread t;
public RunThread(t,ArrayList<String> vec, int threadNbr,Matrix ma) {
this.t = t;
super("","");
this.vec=vec;this.threadNbr=threadNbr;this.ma=ma; }
#Override
public void run() {
FileInputStream fin = null;
try {
fin = new FileInputStream(ma.getNom()+threadNbr+".txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Scanner sc = new Scanner(fin);
while (sc.hasNext()) {
String nextString = sc.next();
ma.nbrLnCol[0]++;
String [] arr = nextString.split(",");
ma.nbrLnCol[1]=arr.length;
double c=0;
for(int j=0;j<arr.length;j++)
{
c+=(Double.parseDouble(arr[j])*Double.parseDouble(vec.get(j)));
}
res[threadNbr-1]=c;
}
sc.close();
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
File file = new File(ma.getNom()+threadNbr+".txt");
file.delete();
if(t!=null){
t.join(); //join with the previous thread eg. thread2 joining with thread1
}
}
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;
}
I am trying to spawn off a handful of threads and place them in a List as they execute. As they complete their processing I would like to collect their results for presentation. That way I can have a list containing many threads and then once they become available I can call future.get and use their callback information.
For some reason, I am missing many of the results. When I step through the code, f.get() is being passed over when it shouldn't be and I cannot figure out why.
My code is as follows:
public class ThreadTesterRunner {
static List<Integer> randoms = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
final Phaser cb = new Phaser();
ThreadRunner tr = new ThreadRunner(cb);
Thread t = new Thread(tr, "Thread Runner");
t.start();
boolean process = true;
// wait until all threads process, then print reports
while (process){
if(tr.isFinished()){
System.out.println("Print metrics");
process = false;
}
Thread.sleep(1000);
}
}
}
class ThreadRunner implements Runnable {
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private final Phaser barrier;
private boolean finished=false;
public ThreadRunner(Phaser phaser) {this.barrier = phaser;}
public void run(){
try {
List<Future<Integer>> list = new ArrayList<>();
boolean stillLoop = true; int i = 0;
final Phaser p = this.barrier;
Callable<Integer> task = new Callable<Integer>() {
public Integer call() throws Exception {
return new Reader().doRun(p);
}
};
List<Integer> randoms = new ArrayList<>();
Integer size;
while (stillLoop){
System.out.println("i "+i);
list.add(executorService.submit(task));
for(Future<Integer> f: list){
if(f.isDone()){
size = f.get();
System.out.println("size "+size);
list.remove(f);
} else {
// keep processing
}
}
if(i == 2){
System.out.println("breaking out of loop");
stillLoop = false;
}
i++;
}
this.barrier.awaitAdvance(0);
this.finished=true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
public boolean isFinished(){
return this.finished;
}
}
class Reader {
private Phaser readBarrier;
private ExecutorService executorService = Executors.newFixedThreadPool(20);
public Reader() {
}
Random randomGenerator = new Random();
public Integer doRun(Phaser phaser) throws Exception {
phaser.register();
this.readBarrier = phaser;
System.out.println("Reading...");
int i;
int r = randomGenerator.nextInt(100);
System.out.println("r "+r);
ThreadTesterRunner.randoms.add(r);
int a = this.readBarrier.arrive();
return r; //i;
}
}
Any idea's as to why this may be happening?
EDIT:
Alright, I think I have it up and running:
class ThreadRunner implements Runnable {
// static int timeOutTime = 2;
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private final Phaser barrier;
private boolean finished = false;
public ThreadRunner(Phaser phaser) {
this.barrier = phaser;
}
public void run() {
try {
List<Future<Integer>> list = new CopyOnWriteArrayList<>();
boolean stillLoop = true;
int i = 0;
final Phaser p = this.barrier;
Callable<Integer> readerTask = new Callable<Integer>() {
public Integer call() throws Exception {
return new Reader().doRun(p);
}
};
List<Integer> randoms = new ArrayList<>();
Integer size;
while (stillLoop) {
if (i <= 2) {
list.add(executorService.submit(readerTask));
}
if (!list.isEmpty()) {
for (Future<Integer> f : list) {
if (f.isDone()) {
size = f.get();
randoms.add(size);
System.out.println("Process read with a size of "+ size);
list.remove(f);
} else {
// System.out.println("skipping");
}
}
} else {
stillLoop = false;
}
i++;
}
System.out.println("at barrier waiting");
this.barrier.awaitAdvance(0);
System.out.println("barrier crossed");
this.finished = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
public boolean isFinished() {
return this.finished;
}
}
Results:
i 0
i 1
i 2
breaking out of loop
Reading...
Reading...
r 13
r 44
Reading...
r 78
Print metrics
I changed the ArrayList to a Vector since ArrayList is not thread safe which would eventually cause a ConcurrentModificationException.
Is the above output what you would expect?
I’m writing a program that implements the Producer Consumer problem in Java using multithreading concepts. Below are few details how I’m supposed to do it:
1) The main thread should create a buffer with capacity specified as a command line argument. The number of producer and consumer threads are also specified as command line arguments. I’m supposed to assign a unique number to each producer and consumer thread. How do I assign a unique number to producer and consumer threads?
2) The producer thread operates in an infinite loop. It produces a data item (a string) with the following format: <producer number>_<data item number>. For example the 1st data item from thread number 1 will be 1_1 and second data item from thread number 3 will be 3_2. How do create data items in such a format?
3) Then the Producer thread writes an entry into the producer log file (< producer number > “Generated” <data item>). Upon writing the log entry, it attempts to insert into the buffer. If insertion is successful, it creates an entry into the log file (<producer number> <data item> “Insertion successful”). How do I write such a code?
Below is the Java code I wrote.
import java.util.*;
import java.util.logging.*;
public class PC2
{
public static void main(String args[])
{
ArrayList<Integer> queue = new ArrayList<Integer>();
int size = Integer.parseInt(args[2]);
Thread[] prod = new Thread[Integer.parseInt(args[0])];
Thread[] cons = new Thread[Integer.parseInt(args[1])];
for(int i=0; i<prod.length; i++)
{
prod[i] = new Thread(new Producer(queue, size));
prod[i].start();
}
for(int i=0; i<cons.length; i++)
{
cons[i] = new Thread(new Consumer(queue, size));
cons[i].start();
}
}
}
class Producer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Producer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true){
for(int i=0; i<size; i++)
{
System.out.println("Produced: "+i+" by id " +Thread.currentThread().getId());
try
{
produce(i);
Thread.sleep(3000);
}
catch(Exception e)
{
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}}
}
public void produce(int i) throws InterruptedException
{
while(queue.size() == size)
{
synchronized(queue)
{
System.out.println("Queue is full "+Thread.currentThread().getName() +" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized(queue)
{
queue.add(i);
queue.notifyAll();
}
}
}
class Consumer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Consumer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true)
{
try
{ System.out.println("Consumed: "+consume());
Thread.sleep(1000);
}
catch(Exception e)
{
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
public int consume() throws InterruptedException
{
while(queue.isEmpty())
{
synchronized(queue)
{
System.out.println("Queue is empty "+Thread.currentThread().getName()+" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized (queue)
{
queue.notifyAll();
System.out.println("Consumed by id "+Thread.currentThread().getId());
return (Integer) queue.remove(0);
}
}
}
How can I carry out the above steps?
I’m supposed to assign a unique number to each producer and consumer
thread. How do I assign a unique number to producer and consumer
threads?
Add an instance (non-static) variable to the Producer/Consumer classes. When you initialize the new Producer/Consumer Objects, pass in the unique number. You can keep track of what number you're on with an int counter in your main class.
2) The producer thread operates in an infinite loop. It produces a
data item (a string) with the following format: < producer number >_<
data item number > . For example the 1st data item from thread number
1 will be 1_1 and second data item from thread number 3 will be 3_2.
How do create data items in such a format?
Use synchronized methods and/or atomic variables. Look into Java Concurrency.
3) Then the Producer thread writes an entry into the producer log file
(< producer number > “Generated” < data item >). Upon writing the log
entry, it attempts to insert into the buffer. If insertion is
successful, it creates an entry into the log file (< producer number >
< data item > “Insertion successful”). How do I write such a code?
My answer is the same as the previous question: read about Java concurrency. Spend an hour reading about synchronization, locks, and atomic variables and I guarantee you will easily write your program.
For producer consumer problem best solution is BlockingQueue. I was testing a few things so designed same kind of program now modified it as per your need.
See if it helps.
import java.util.concurrent.*;
public class ThreadingExample {
public static void main(String args[]){
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(100);
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Producer(blockingQueue));
exec.execute(new Consumer(blockingQueue));
}
}
class Message{
private static int count=0;
int messageId;
Message(){
this.messageId=count++;
System.out.print("message Id"+messageId+" Created ");
}
}
class Producer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Producer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Producer Started");
try {
blockingQueue.put(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer Done");
}
}
}
class Consumer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Consumer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Concumer Started");
try{
Message message = blockingQueue.take();
System.out.print("message Id"+message.messageId+" Consumed ");
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Concumer Done");
}
}
}
I tried the following which might work for you, except for the buffer condition on 3, which you can add the part of the code by yourself.
Hope this helps.
public class Message {
private String msg;
public Message(String msg) {
super();
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable {
private BlockingQueue<Message> queue;
private boolean run = true;
public Producer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val) {
this.run = val;
}
#Override
public void run() {
int i = 0;
while (run) {
Message msg = new Message(Thread.currentThread().getName() + "_"+ i);
try {
Thread.sleep(i * 100);
queue.put(msg);
System.out.println("Producer: "+Thread.currentThread().getName()+" produced and added to the queue: "+msg.getMsg());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if(i==10){
setRun(false);
System.out.println(Thread.currentThread().getName()+" stopped");
}
}
}
}
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Message> queue;
private boolean run = true;
public Consumer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val){
this.run = val;
}
#Override
public void run() {
while(run){
try {
Thread.sleep(100);
Message msg = queue.take();
System.out.println("Consumer: "+Thread.currentThread().getName()+" generated/consumed "+msg.getMsg());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerMain {
public static void main(String[] args) {
System.out
.println("please enter the number of producer:consumer:size of the queue in order");
Scanner scan = new Scanner(System.in);
Thread[] prodThreads = new Thread[scan.nextInt()];
Thread[] consThreads = new Thread[scan.nextInt()];
BlockingQueue<Message> queue = new ArrayBlockingQueue<Message>(scan.nextInt());
for (int i = 0; i < prodThreads.length; i++) {
prodThreads[i] = new Thread(new Producer(queue), "" + i);
prodThreads[i].start();
}
for (int i = 0; i < consThreads.length; i++) {
consThreads[i] = new Thread(new Consumer(queue), "" + i);
consThreads[i].start();
}
}
}
Please refer the below code. You can change the constant values based on the command line arguments. I have tested the code, its working as per your requirement.
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerProblem {
public static int CAPACITY = 10; // At a time maximum of 10 tasks can be
// produced.
public static int PRODUCERS = 2;
public static int CONSUMERS = 4;
public static void main(String args[]) {
Queue<String> mTasks = new LinkedList<String>();
for (int i = 1; i <= PRODUCERS; i++) {
Thread producer = new Thread(new Producer(mTasks));
producer.setName("Producer " + i);
producer.start();
}
for (int i = 1; i <= CONSUMERS; i++) {
Thread consumer = new Thread(new Consumer(mTasks));
consumer.setName("Consumer " + i);
consumer.start();
}
}
}
class Producer implements Runnable {
Queue<String> mSharedTasks;
int taskCount = 1;
public Producer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
#Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
try {
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY) {
System.out.println("Producer Waiting!!");
mSharedTasks.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (mSharedTasks.size() != ProducerConsumerProblem.CAPACITY) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
String produceHere = Thread.currentThread().getName()
+ "_Item number_" + taskCount++;
synchronized (mSharedTasks) {
mSharedTasks.add(produceHere);
System.out.println(produceHere);
if (mSharedTasks.size() == 1) {
mSharedTasks.notifyAll(); // Informs consumer that there
// is something to consume.
}
}
}
}
}
}
class Consumer implements Runnable {
Queue<String> mSharedTasks;
public Consumer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
#Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
if (mSharedTasks.isEmpty()) { // Checks whether there is no task
// to consume.
try {
mSharedTasks.wait(); // Waits for producer to produce!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
while (!mSharedTasks.isEmpty()) { // Consumes till task list is
// empty
try {
// Consumer consumes late hence producer has to wait...!
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (mSharedTasks) {
System.out.println(Thread.currentThread().getName()
+ " consumed " + mSharedTasks.poll());
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY - 1)
mSharedTasks.notifyAll();
}
}
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #"
+ this.number
+ " got: " + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
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