I am completely new to multi threading. Need assistance on the below scenario
Scenario:- I want two threads to execute, such that they have to print the word "PingPong" alternatively. This has to happen three 3 times for both threads.
For example:-
- Thread 1 has to print "Ping" and it has to go to wait stage.
- Thread 2 has to print "Ping" and it has to go to wait stage as well as notify the other thread.
- Thread 1 has to print "Pong" and it has to go to wait stage as well as notify the other thread.
- Thread 2 has to print "Pong" and it has to go to wait stage as well as notify the other thread.
The same way both the threads has to print the word 3 times in total.
Coding below:-
package com.test.files;
public class MultiThreadingTest2 implements Runnable {
String lastExecutedThread = "";
Object lockObj = new Object();
private void print(String wordToPrint) throws InterruptedException {
synchronized(lockObj) {
if(lastExecutedThread.equals(Thread.currentThread().getName())) {
System.out.println(Thread.currentThread().getName() " entered wait stage");
lockObj.wait();
} else {
lastExecutedThread = Thread.currentThread().getName();
System.out.println(Thread.currentThread().getName() " printed " wordToPrint);
lockObj.notifyAll();
}
}
}
public MultiThreadingTest2(Object lock) {
this.lockObj = lock;
}
@Override
public void run() {
String[] wordArr = {"Ping", "Pong"};
for(int i = 0; i < 3; i ) {
for(int j = 0; j < wordArr.length; j ) {
try {
print(wordArr[j]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread t1 = new Thread(new MultiThreadingTest2(lock), "Thread 1");
Thread t2 = new Thread(new MultiThreadingTest2(lock), "Thread 2");
t1.start();
t2.start();
}
}
But I could see the above code has resulted in deadlock. Output as follow:-
Thread 1 printed Ping
Thread 1 entered wait stage
Thread 2 printed Ping
Thread 2 entered wait stage
Thread 1 entered wait stage
I am not sure why this has resulted in deadlock. Reason because, the variable "lastExecutedThread " is created at class level. So it should be stored in heap. If its a local variable, then we can say that it could be in thread stack, so the other thread may not what value it possess and because of which the thread executing the print function will have the "lastExecutedThread" to its name and it will lead to deadlock.
Could you please help on this.
CodePudding user response:
You have to make lastExecutedThread
static, otherwise each Thread
sees its own instance of it.
Note that if inside the print
method lockObj.wait()
is called, the wordToPrint
passed to this method is never printed. You can slightly adapt your code to avoid this: if your print
method returns true
if printing was successful, and false
otherwise. Then inside your nested for-loop, put your call of print
inside a while-loop: while (!print(wordArr[j]));