Print Zero Even Odd Multithreading Java - java

I am trying to solve the issue, but the program only shows the below output and halts.
My question is: why the notifiall() call in printZero() does not result in releasing the wait on other threads?
Output: Waiting evenWaiting oddZero0notified
Program:
package com.leetcode.problems;
import java.util.ArrayList;
import java.util.List;
public class PrintZeroEvenOdd {
private class Printer {
int temp= 0;
int i = 0;
List list = new ArrayList();
public synchronized void printZero(){
if((temp) > 0 || temp < 0){
try{
wait();
} catch(InterruptedException e){
}
}
System.out.print("Zero" + 0);
if(temp%2 == 0){
temp = temp -1;
} else if(temp%2 == 1){
temp = 1 - temp;
}
i++;
notifyAll();
System.out.print("notified");
}
public synchronized void printOdd(){
if(( temp == 0 || (temp % 2) == 0)){
try{
System.out.print("Waiting odd");
wait();
} catch(InterruptedException e){
}
}
System.out.println("Odd"+i);
temp = 1- temp;
i++;
notifyAll();
}
public synchronized void printEven(){
if(( temp == 0 || (temp % 2) == 1)){
try{
System.out.print("Waiting even");
wait();
} catch(InterruptedException e){
}
}
System.out.println("Even"+i);
temp = temp -1;
i++;
notifyAll();
}
}
transient int i = 0;
private class ZeroPrinter implements Runnable{
Printer printer ;
ZeroPrinter( ){
printer = new Printer();
}
#Override
public void run(){
while(i<20)
printer.printZero();
}
}
private class OddPrinter implements Runnable{
Printer printer ;
OddPrinter( ){
printer = new Printer();
}
#Override
public void run(){
while(i<20)
printer.printOdd();
}
}
private class EvenPrinter implements Runnable{
Printer printer ;
EvenPrinter(){
printer = new Printer();
}
#Override
public void run(){
while(i<20)
printer.printEven();
}
}
public static void main(String[] argw) throws InterruptedException{
PrintZeroEvenOdd printZeroEvenOdd = new PrintZeroEvenOdd();
Thread printEvenThread = new Thread(printZeroEvenOdd.new EvenPrinter());
Thread printZeroThread = new Thread(printZeroEvenOdd.new ZeroPrinter());
Thread printOddThread = new Thread(printZeroEvenOdd.new OddPrinter());
printEvenThread.start();
Thread.sleep(1000);
printOddThread.start();
Thread.sleep(100);
printZeroThread.start();
}
}

Each Thread is synchronizing (holding the lock) on its own instance of Printer (as you are creating a new Printer instance in each of the 3 constructors), so notifyAll() doesn't result in the other threads waking up, since they are waiting on different monitors (difference object instances of Printer).
The printZeroThread is printing the output that you see because it's never entering the condition if((temp) > 0 || temp < 0).
I am not sure exactly what your program is trying to achieve, but it surely seems like it should be working on a single instance of Printer.
It seems that, in your private classes you should remove the new Printer() and use the enclosing class instead, for example in Zero printer I've commneted out the parts that needs to be removed:
private class ZeroPrinter implements Runnable{
// Printer printer ;
// ZeroPrinter( ){
// printer = new Printer();
// }
#Override
public void run(){
while(i<20)
// printer.
printZero();
}
}
The same should be done for EvenPrinter and OddPrinter, then these private classes will use the encolsing instace of Printer, so there will be one monitor common for these instances.

Sure, Here is the Program as corrected :-
package com.leetcode.problems;
import java.util.ArrayList;
import java.util.List;
public class PrintZeroEvenOdd {
private class Printer {
int temp = 2;
int i = 0;
List list = new ArrayList();
public Printer() {
};
public synchronized void printZero() {
while (i < 19) {
if ((temp) == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
System.out.print(0);// System class is a final class , and thus
// only one threead will take control
temp = 0;
i++;
notifyAll();
// System.out.print("notified");
}
}
public synchronized void printOdd() {
while (i < 19) {
if (((temp) != 0)) {
try {
wait();
} catch (InterruptedException e) {
}
}
if ((i % 2) == 1) {
System.out.println(i);
notifyAll();
}
temp = 1;
}
}
public synchronized void printEven() {
while (i < 19) {
if (temp != 0) {
try {
// System.out.print("Waiting even");
wait();
} catch (InterruptedException e) {
}
}
if ((i % 2) == 0) {
System.out.println(i);
notifyAll();
}
temp = 1;
}
}
}
transient int i = 0;
private class ZeroPrinter implements Runnable {
Printer printer;
ZeroPrinter(Printer printer) {
this.printer = printer;
}
#Override
public void run() {
printer.printZero();
}
}
private class OddPrinter implements Runnable {
Printer printer;
OddPrinter(Printer printer) {
this.printer = printer;
}
#Override
public void run() {
printer.printOdd();
}
}
private class EvenPrinter implements Runnable {
Printer printer;
EvenPrinter(Printer printer) {
this.printer = printer;
}
#Override
public void run() {
printer.printEven();
}
}
public static void main(String[] argw) throws InterruptedException {
PrintZeroEvenOdd printZeroEvenOdd = new PrintZeroEvenOdd();
Printer printer = printZeroEvenOdd.new Printer();
Thread printEvenThread = new Thread(printZeroEvenOdd.new EvenPrinter(
printer));
Thread printZeroThread = new Thread(printZeroEvenOdd.new ZeroPrinter(
printer));
Thread printOddThread = new Thread(printZeroEvenOdd.new OddPrinter(
printer));
// Above order does not matter
// In short , in MT Order to start the threads does not matter at all
printEvenThread.start();
Thread.sleep(1000);
printOddThread.start();
Thread.sleep(100);
printZeroThread.start();
}
}

Related

How can I distinguish a winner in this thread race?

I have been writing a race code for a class I am in that races two threads, a tortoise and a hare. I can get both of them to run for 80 units but I don't know how to write a code that determines and outputs who the winner is. Any help would be appreciated because I am super new to coding.
I have the tortoise, hare, and raceParticipant classes. My driver class looks like this, where I would assume I put the winner code?
package Domain;
public class Driver
{
public static void main(String[] args)
{
Hare bob = new Hare();
Tortoise fred = new Tortoise();
int winDistance = 80;
do {
bob.sprint();
fred.sprint();
bob.display();
fred.display();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
}
}
My sprint method is
public int sprint()
{
int sleep = generator.nextInt(100);
int sprintDistance = 0;
if (sleep > sleepPercent)
{
sprintDistance = generator.nextInt(topSpeed) + 1;
}
totalDistance +=sprintDistance;
return sprintDistance;
}
I don't see you creating a new thread anywhere.
You can create a Hare class like this:
public class Hare implements Runnable {
private static final int SLEEP_DURATION = 3000; //milliseconds
private static final int SPEED = 3; //units per second
private int distanceToRun;
private final RaceFinishListener listener;
public Hare(int distanceToRun, RaceFinishListener listener) {
this.distanceToRun = distanceToRun;
this.listener = listener;
}
#Override
public void run() {
do {
distanceToRun -= SPEED;
try {
Thread.sleep(SLEEP_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (distanceToRun > 0);
listener.onRaceFinished(getClass().getSimpleName());
}
}
and a similar Tortoise class with these variables:
private static final int SLEEP_DURATION = 1000; //sleeps less
private static final int SPEED = 1; //but is slow
Then create a listener to get notified when someone has finished:
public interface RaceFinishListener {
void onRaceFinished(String finisher);
}
and finally your main class:
public class Test implements RaceFinishListener {
private String winner;
private static final int DISTANCE_TO_RUN = 10;
public static void main(String[] args) {
new Test().race();
}
private void race() {
Hare bob = new Hare(DISTANCE_TO_RUN, this);
Tortoise fred = new Tortoise(DISTANCE_TO_RUN, this);
new Thread(bob).start();
new Thread(fred).start();
}
#Override
public void onRaceFinished(String finisher) {
synchronized (this) {
if (winner == null) {
winner = finisher;
System.out.println(finisher + " is the winner!");
} else {
System.out.println(finisher + " lost.");
}
}
}
}
Output
Tortoise is the winner!
Hare lost.
After this line:
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
You would just have:
boolean bobWins = (bob.getTotalDistance() >= winDistance);
boolean fredWins = (fred.getTotalDistance() >= winDistance);
if (bobWins && fredWins) {
System.out.println("It's a tie");
}
else if (bobWins) {
System.out.println("Bob Wins");
}
else {
System.out.println("Fred Wins");
}

Print Floyd triangle using multithreading in java

I want to use two threads to print Floyd triangle(say one thread prints the number and the other prints the number in the line) as below.
and so forth until the max number which is 15 in this case.
I tried following but it keeps on printing numbers one on each line
public class MyThread extends Thread{
static volatile int lineNumber = 1;
public static void main(String... args) {
PrintFloyd print = new PrintFloyd();
Thread t1 = new Thread(new TaskHandler(print, 10), "T1");
Thread t2 = new Thread(new TaskHandler(print, 10), "T2");
t1.start();
t2.start();
}
}
class TaskHandler implements Runnable {
static volatile int i = 1;
static volatile int lineCount = 1;
static volatile int lineNumber = 1;
private int max;
private PrintFloyd print;
TaskHandler(PrintFloyd print2, int max) {
this.print = print2;
this.max = max;
}
#Override
public void run() {
System.out.println(">>>>" + Thread.currentThread().getName());
while(i < max){
if (Thread.currentThread().getName().equals("T1")){
print.printNumber(i);
} else {
print.breakLine();
}
}
}
}
class PrintFloyd {
boolean isBreakPoint = false;
public void printNumber(int i) {
synchronized(this){
while (isBreakPoint == false) {
try {
wait();
} catch (InterruptedException ex) {
}
System.out.print(i++ + " ");
isBreakPoint = false;
notifyAll();
}
}
}
public void breakLine(){
synchronized(this){
while (isBreakPoint == true) {
try {
wait();
} catch (InterruptedException ex) {
}
}
System.out.println();
isBreakPoint = true;
notifyAll();
}
}
}
The following code would help:
public class PrintPatternWith2Threads {
final static int MAX = 15;
final static String itemWriterName = "itemWriter";
final static String newLineWriterName = "newLineWriter";
public static void main(String[] args) {
Printer print = new Printer(MAX);
Thread itemWriter = new Thread(new ItemWriter(print), itemWriterName);
itemWriter.start();
Thread newLineWriter = new Thread(new NewLineWriter(print), newLineWriterName);
newLineWriter.start();
}
}
class ItemWriter implements Runnable {
private Printer print;
ItemWriter(Printer print) {
this.print = print;
}
public void run() {
while (print.current <= print.MAX) {
print.printNumber();
}
}
}
class NewLineWriter implements Runnable {
private Printer print;
NewLineWriter(Printer print) {
this.print = print;
}
public void run() {
while (print.current <= print.MAX) {
print.printNewLine();
}
}
}
class Printer {
public final int MAX;
public int current = 1;
public int itemsInALine = 1;
Printer(int max) {
this.MAX = max;
}
public void printNumber() {
synchronized(this) {
for(int i = current; i < current + itemsInALine && i <= MAX; i++) {
System.out.print(i + " ");
}
this.current = current + itemsInALine;
itemsInALine++;
notifyAll();
try {
if(this.current < MAX) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void printNewLine() {
synchronized(this) {
System.out.println();
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

How to execute four threads consecutively one by one in java? [duplicate]

I have 3 threads
1st printing A
2nd printing B
3rd printing C
I want to print in sequence A B C A B C A B C and so on.....
So I wrote the program below, but I am not able to achieve the same.
I am aware of the problem that when status=1 at that time say for example B1 and C1 thread are waiting and when I do notifyAll() both waiting thread wake up and depending on CPU allocation it might print B or C.
in this case I want only B to be printed after A.
what modification I need to do.
public class NotifyAllExample {
int status=1;
public static void main(String[] args) {
NotifyAllExample notifyAllExample = new NotifyAllExample();
A1 a=new A1(notifyAllExample);
B1 b=new B1(notifyAllExample);
C1 c=new C1(notifyAllExample);
a.start();
b.start();
c.start();
}
}
class A1 extends Thread{
NotifyAllExample notifyAllExample;
A1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}
#Override
public void run() {
try{
synchronized (notifyAllExample) {
for (int i = 0; i < 100; i++) {
if(notifyAllExample.status!=1){
notifyAllExample.wait();
}
System.out.print("A ");
notifyAllExample.status = 2;
notifyAllExample.notifyAll();
}
}
}catch (Exception e) {
System.out.println("Exception 1 :"+e.getMessage());
}
}
}
class B1 extends Thread{
NotifyAllExample notifyAllExample;
B1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}
#Override
public void run() {
try{
synchronized (notifyAllExample) {
for (int i = 0; i < 100; i++) {
if(notifyAllExample.status!=2){
notifyAllExample.wait();
}
System.out.print("B ");
notifyAllExample.status = 3;
notifyAllExample.notifyAll();
}
}
}catch (Exception e) {
System.out.println("Exception 2 :"+e.getMessage());
}
}
}
class C1 extends Thread{
NotifyAllExample notifyAllExample;
C1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}
#Override
public void run() {
try{
synchronized (notifyAllExample) {
for (int i = 0; i < 100; i++) {
if(notifyAllExample.status!=3){
notifyAllExample.wait();
}
System.out.print("C ");
notifyAllExample.status = 1;
notifyAllExample.notifyAll();
}
}
}catch (Exception e) {
System.out.println("Exception 3 :"+e.getMessage());
}
}
}
Convert those IF statements to WHILE statements to get the desired behavior:
if (notifyAllExample.status != 2){
notifyAllExample.wait();
}
to
while (notifyAllExample.status != 2){
notifyAllExample.wait();
}
This will ensure that if a thread is notified, it won't go out of the while loop until the status value is what it expects.
Also, mark status as volatile so that the threads won't have a local copy.
public class RunThreadsInOrder implements Runnable {
static int numThread = 1;
static int threadAllowedToRun = 1;
int myThreadID;
private static Object myLock = new Object();
public RunThreadsInOrder() {
this.myThreadID = numThread++;
System.out.println("Thread ID:" + myThreadID);
}
#Override
public void run() {
synchronized (myLock) {
while (myThreadID != threadAllowedToRun) {
try {
myLock.wait();
} catch (InterruptedException e) {
} catch (Exception e) {}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("myThreadID is running: " + myThreadID);
myLock.notifyAll();
threadAllowedToRun++;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1 = new Thread(new RunThreadsInOrder());
Thread t2 = new Thread(new RunThreadsInOrder());
Thread t3 = new Thread(new RunThreadsInOrder());
Thread t4 = new Thread(new RunThreadsInOrder());
Thread t5 = new Thread(new RunThreadsInOrder());
Thread t6 = new Thread(new RunThreadsInOrder());
Thread t7 = new Thread(new RunThreadsInOrder());
t7.start();
t6.start();
t5.start();
t4.start();
t3.start();
t2.start();
t1.start();
}
}
public class Main {
public static void main(String[] args) throws IOException{
Thread t1 = new Thread(new A(), "1");
Thread t2 = new Thread(new A(), "2");
Thread t3 = new Thread(new A(), "3");
t1.start();
try{
t1.join();
}catch (Exception e){
}
t2.start();
try{
t2.join();
}catch (Exception e){
}
t3.start();
try{
t3.join();
}catch (Exception e){
}
}
}
class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
or you can use Executor Framework
public class Sequence {
int valve = 1;
public static void main(String[] args){
Sequence s = new Sequence();
ExecutorService es = Executors.newFixedThreadPool(3);
List<Runnable> rList = new ArrayList<>();
rList.add(new A(s));
rList.add(new B(s));
rList.add(new C(s));
for(int i = 0; i < rList.size(); i++){
es.submit(rList.get(i));
}
es.shutdown();
}
}
class A implements Runnable{
Sequence s;
A(Sequence s){
this.s = s;
}
public void run(){
synchronized (s) {
for (int i = 0; i < 10; i++) {
while (s.valve != 1) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A");
s.valve = 2;
s.notifyAll();
}
}
}
}
class B implements Runnable{
Sequence s;
B(Sequence s){
this.s = s;
}
public void run() {
synchronized (s) {
for (int i = 0; i < 10; i++) {
while (s.valve != 2) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("B");
s.valve = 3;
s.notifyAll();
}
}
}
}
class C implements Runnable{
Sequence s;
C(Sequence s){
this.s = s;
}
public void run() {
synchronized (s) {
for(int i = 0; i < 10; i++) {
while (s.valve != 3) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("C");
s.valve = 1;
s.notifyAll();
}
}
}
}
In the first case the join for each thread causes the threads to wait for one another. In the second case a list stores the threads and executor executes them one after another creating 3 threads
Another way to do this is where only one runnable class is present and communication between thread is done via static variable in the main class and a variable in the runnable class
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Seq {
int i = 1;
public static void main(String[] args){
Seq s = new Seq();
Common c1 = new Common(s, 1);
Common c2 = new Common(s, 2);
Common c3 = new Common(s, 3);
List<Runnable> l = new ArrayList<>();
l.add(c1);
l.add(c2);
l.add(c3);
ExecutorService es = Executors.newFixedThreadPool(3);
for(int i = 0; i < 3; i++){
es.submit(l.get(i));
}
es.shutdown();
}
}
class Common implements Runnable{
Seq s;
int o;
Common(Seq s, int o){
this.s = s;
this.o = o;
}
public void run(){
synchronized (s) {
for (int z = 0; z < 100; z++) {
if(s.i > 3)
s.i = 1;
while (s.i != o) {
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(o);
s.i++;
s.notifyAll();
}
}
}
}
I was asked to write a similar program in an interview with the added condition that it should be extensible in a way that we can provide our own count of threads and they should print characters with the first thread printing 'A' and then the subsequent threads printing B, C, D and so on. Here's how I did it.
public class AlternateCharPrinter {
public static char ch = 65;
private static void createAndStartThreads(int count) {
Object lock = new Object();
for (int i = 0; i < count; i++) {
new Thread(new AlternateCharRunner((char) (65 + i), lock)).start();
}
}
public static void main(String[] args) {
createAndStartThreads(4);
}
}
class AlternateCharRunner implements Runnable {
private char ch;
private Object lock;
private static int runnerCount;
public AlternateCharRunner(char ch, Object lock) {
this.ch = ch;
this.lock = lock;
runnerCount++;
}
#Override
public void run() {
while (true) {
synchronized (lock) {
while (ch != AlternateCharPrinter.ch) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(AlternateCharPrinter.ch++);
if (AlternateCharPrinter.ch == (65 + runnerCount)) {
AlternateCharPrinter.ch = 65;
}
lock.notifyAll();
}
}
}
}
You need to replace
if (notifyAllExample.status!=1)
with
while (notifyAllExample.status!=1)
and same thing in the other 2 classes. If not, then as soon as the wait exits the thread continues without knowing if it is its turn.
Replace:
if(notifyAllExample.status!=1){
notifyAllExample.wait();
}
with:
while(notifyAllExample.status!=1){
notifyAllExample.wait();
}
in all classes accordingly.
The simplest solution to solve this can be following way:
public class PrintInOrder implements Runnable {
private int valueToPrint;
private int id;
private static int turn = 1;
private static int RESET_TURN_THRESHOLD = 3;
public PrintInOrder() {
this.valueToPrint = -1;
}
public PrintInOrder(int id, int val) {
this.id = id;
this.valueToPrint = val;
}
#Override
public void run() {
while(true) {
if (turn == this.id) {
System.out.println(Thread.currentThread().getName() + "::::" + valueToPrint);
turn++;
}
if (turn > RESET_TURN_THRESHOLD) {
turn = 1;
}
}
}
public static void main(String []args) {
Thread t1 = new Thread(new PrintInOrder(1, 1));
t1.setName("THREAD-1");
t1.start();
Thread t2 = new Thread(new PrintInOrder(2, 2));
t2.setName("THREAD-2");
t2.start();
Thread t3 = new Thread(new PrintInOrder(3, 3));
t3.setName("THREAD-3");
t3.start();
}
}
/*
OUTPUT::::
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
THREAD-1::::1
THREAD-2::::2
THREAD-3::::3
...
*/
Here is my solution -
I have created three threads each thread knows what it needs to print and what comes after it.
I have also created a Class NLock which holds the next word which needs to be printed.
Whenever a thread is able to acquire NLock lock then it checks
if it's his turn if yes then it prints the word and set the next value to be printed in NLock or else it waits till it's his turn
public class SynchronizeThreeThreads {
public static void main(String args[]) throws InterruptedException {
NLock lock=new NLock("A");
Thread a =new Thread(new PrintInOrder("A","B",lock));
Thread b =new Thread(new PrintInOrder("B","C",lock));
Thread c =new Thread(new PrintInOrder("C","A",lock));
a.start();
b.start();
c.start();
c.join(); // Once all is done main thread will exit
System.out.println("Done");
}
}
class NLock{
private String value;
public NLock(String value) {
this.value=value;
}
public String getValue() {
return value;
}
public void setValue(String next) {
this.value=next;
}
}
class PrintInOrder implements Runnable{
private String word;
private String next;
private NLock lock;
public PrintInOrder(String word, String next,NLock lock){
this.word=word;
this.next=next;
this.lock=lock;
}
#Override
public void run() {
int i=0;
while(i<3) {
synchronized (lock) {
try {
//Check if it's my turn
if(lock.getValue().equals(word)) {
System.out.println(this.word);
//Set what next needs to be printed
//So that when that thread wakes up it knows that it's his turn
lock.setValue(next);
i++;
lock.notifyAll();
Thread.sleep(100);
}
else //Nope not my turn wait
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Below is the output
A
B
C
A
B
C
A
B
C
Done
This is my attempt to solve the same. Any suggestions are welcome. This is the complete running code.
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
#Slf4j
public class SeqExecution {
static class SeqThread extends Thread {
private static final Object lock = new Object();
private static final AtomicInteger AUTO_COUNTER = new AtomicInteger();
private static final TrackExecution trackExecution = new TrackExecution();
private final int seqNo;
SeqThread(Runnable runnable) {
super(runnable);
this.seqNo = AUTO_COUNTER.getAndIncrement();
}
#SneakyThrows
#Override
public void run() {
while (true) {
synchronized (lock) {
while (trackExecution.CUR_EXECUTION.get() != this.seqNo) {
try {
lock.wait(100);
} catch (Exception e) {}
}
//log.info("Thread: {} is running", this.seqNo);
super.run();
sleep(1000);
trackExecution.increment();
lock.notifyAll();
}
}
}
static class TrackExecution {
private final AtomicInteger CUR_EXECUTION = new AtomicInteger();
int get() {
return CUR_EXECUTION.get();
}
synchronized void increment() {
var val = CUR_EXECUTION.incrementAndGet();
if (val >= SeqThread.AUTO_COUNTER.get()) {
CUR_EXECUTION.set(0);
}
}
}
}
public static void main(String[] args) {
final var seqThreads = List.of(new SeqThread(() -> System.out.print("A ")),
new SeqThread(() -> System.out.print("B ")),
new SeqThread(() -> System.out.print("C ")));
seqThreads.forEach(Thread::start);
seqThreads.forEach(t -> {
try {
t.join();
} catch (Exception e) {
log.warn(e.getMessage(), e);
}
});
}
}
I think it's simpler to achieve this using join.
Example:
public static void main(String[] args) {
final Thread t1 = new Thread("t1") {
#Override
public void run() {
System.out.println("i am thread: " + Thread.currentThread().getName());
}
};
final Thread t2 = new Thread(t1, "t2") {
#Override
public void run() {
t1.start();
try {
t1.join();
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("i am thread: " + Thread.currentThread().getName());
}
};
Thread t3 = new Thread(t2, "t3") {
#Override
public void run() {
t2.start();
try {
t2.join();
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("i am thread: " + Thread.currentThread().getName());
}
};
t3.start();
}
Here is my solution please try and let me know
package thread;
class SyncPrinter {
public static void main(String[] args) {
SyncPrinterAction printAction1 = new SyncPrinterAction(new int[]{1,5,9,13}, true);
SyncPrinterAction printAction2 = new SyncPrinterAction(new int[]{2,6,10,14}, true);
SyncPrinterAction printAction3 = new SyncPrinterAction(new int[]{3,7,11,15}, true);
SyncPrinterAction printAction4 = new SyncPrinterAction(new int[]{4,8,12,16}, false);
printAction1.setDependentAction(printAction4);
printAction2.setDependentAction(printAction1);
printAction3.setDependentAction(printAction2);
printAction4.setDependentAction(printAction3);
new Thread(printAction1, "T1").start();;
new Thread(printAction2, "T2").start();
new Thread(printAction3, "T3").start();
new Thread(printAction4, "T4").start();
}
}
class SyncPrinterAction implements Runnable {
private volatile boolean dependent;
private SyncPrinterAction dependentAction;
int[] data;
public void setDependentAction(SyncPrinterAction dependentAction){
this.dependentAction = dependentAction;
}
public SyncPrinterAction( int[] data, boolean dependent) {
this.data = data;
this.dependent = dependent;
}
public SyncPrinterAction( int[] data, SyncPrinterAction dependentAction, boolean dependent) {
this.dependentAction = dependentAction;
this.data = data;
this.dependent = dependent;
}
#Override
public void run() {
synchronized (this) {
for (int value : data) {
try {
while(dependentAction.isDependent())
//System.out.println("\t\t"+Thread.currentThread().getName() + " :: Waithing for dependent action to complete");
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
dependentAction.setDependent(true);
System.out.println(Thread.currentThread().getName() + " :: " +value);
dependent = false;
}
}
}
private void setDependent(boolean dependent) {
this.dependent = dependent;
}
private boolean isDependent() {
return dependent;
}
}

Confused about how to use exchanger in java

As with basically every exchanger task, I have a producer filling up an empty buffer2, a consumer clearing a full buffer1 and when each thread is done, they should exchange their respective buffers.
I am really unsure about where and how to apply the exchange. I defined readyconsumer and readyproducer as booleans, so that a third thread can check whether it's time to exchange the buffers once both are true. This should solve the problem I had doing it with two threads, where the program was stuck with both threads at wait() (which it unfortunately still is).
This is what the code looks like at the moment. Can anyone help me in which class I have to exchange and at what point in the code? Thank you very much in advance!
class Buffer {
static boolean readyconsumer, readyproducer = false;
volatile int count; // number of put actions
static int max = 10;
Buffer() {
count = 0;
}
public synchronized void put() {
if (count == max) {
readyproducer = true;
System.out.println(" wait ");
try {
wait();
} catch (InterruptedException e) {
}
}
count++;
System.out.println("put " + count);
notifyAll();
}
public synchronized void get() {
if (count == 0) {
readyconsumer = true;
System.out.println(" wait");
try {
wait();
} catch (InterruptedException e) {
}
}
count--;
System.out.println("get " + count);
notifyAll();
}
}
class CheckandSwitch extends ProdCon {
public void run() {
while (true) {
if (Buffer.readyconsumer && Buffer.readyproducer) {
try {
ProdCon.buffer2 = exchanger.exchange(ProdCon.buffer1);
ProdCon.buffer1 = exchanger.exchange(ProdCon.buffer2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Buffer.readyconsumer = false;
Buffer.readyproducer = false;
buffer1.count = 0;
buffer2.count = 10;
notifyAll();
}
}
}
}
class Consumer extends ProdCon {
static Buffer buffer;
Consumer(Buffer b) {
super();
buffer = b;
b.count = 10;
}
public void run() {
while (true) {
consume();
buffer.get();
}
}
private void consume() {
System.out.println("consume");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
class Producer extends ProdCon {
static Buffer buffer;
Producer(Buffer b) {
super();
buffer = b;
b.count = 0;
}
public void run() {
while (true) {
produce();
buffer.put();
}
}
private void produce() {
System.out.println("produce ");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
import java.util.concurrent.*;
public class ProdCon extends Thread {
static Exchanger<Buffer> exchanger = new Exchanger<Buffer>();
static Buffer buffer1, buffer2 = null;
public static void main(String[] args) {
buffer1 = new Buffer();
buffer2 = new Buffer();
new Consumer(buffer1).start();
new Producer(buffer2).start();
new CheckandSwitch().start();
}
}
You could use an Exchanger.
Here's the code from the javadoc tweaked into a working example.
class DataBuffer<T> {
T data = null;
public boolean isFull() {
return data != null;
}
public boolean isEmpty() {
return data == null;
}
public T get() {
T d = data;
data = null;
return d;
}
public void put(T data) {
this.data = data;
}
}
class FillAndEmpty {
Exchanger<DataBuffer<Integer>> exchanger = new Exchanger<>();
DataBuffer<Integer> initialEmptyBuffer = new DataBuffer<>();
DataBuffer<Integer> initialFullBuffer = new DataBuffer<>();
int countDown = 10;
class FillingLoop implements Runnable {
#Override
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null && countDown > 0) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void addToBuffer(DataBuffer<Integer> currentBuffer) {
currentBuffer.put(countDown--);
}
}
class EmptyingLoop implements Runnable {
#Override
public void run() {
DataBuffer<Integer> currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void takeFromBuffer(DataBuffer<Integer> currentBuffer) {
System.out.println(currentBuffer.get());
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}
public void test() {
System.out.println("Hello");
new FillAndEmpty().start();
}

How to debug multi threaded java program

I have program and I have set some debug point in it,but when control reached to the wait method in side the printEven method, control goes to till wait method and become hidden and nothing happened. Can any one explain how to debug wait. Control goes to wait method and never return.I am using eclipse to debug it.
public class PrintEvenOddTester
{
public static void main(String ... args)
{
Printer print = new Printer();
Thread t1 = new Thread(new TaskEvenOdd(print, 10, false));
Thread t2 = new Thread(new TaskEvenOdd(print, 10, true));
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable
{
private int max;
private Printer print;
private boolean isEvenNumber;
TaskEvenOdd(Printer print, int max, boolean isEvenNumber)
{
this.print = print;
this.max = max;
this.isEvenNumber = isEvenNumber;
}
public void run()
{
//System.out.println("Run method");
int number = isEvenNumber == true ? 2 : 1;
while(number<= max)
{
if(isEvenNumber)
{
//System.out.println("Even :"+ Thread.currentThread().getName());
print.printEven(number);
// number+=2;
}
else
{
//System.out.println("Odd :"+ Thread.currentThread().getName());
print.printOdd(number);
// number+=2;
}
number+=2;
}
}
}
class Printer
{
boolean isOdd= false;
synchronized void printEven(int number)
{
while(isOdd == false)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("Even:"+number);
isOdd = false;
notifyAll();
}
synchronized void printOdd(int number)
{
while(isOdd == true)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("Odd:"+number);
isOdd = true;
notifyAll();
}
}

Categories