I\'m trying to understand thread basics, and as a first example I create two thread that write a String on the stdout. As I know the scheduler allows to execute the threads
One of the possible implementations:
public class PingPongDemo {
private static final int THREADS = 2;
private static int nextIndex = 0;
private static String getMessage(int index) {
return index % 2 == 0 ? "ping" : "pong";
}
public static void main(String[] args) throws Throwable {
var lock = new ReentrantLock();
var conditions = new Condition[THREADS];
for (int i = 0; i < conditions.length; i++) {
conditions[i] = lock.newCondition();
}
for (int i = 0; i < THREADS; i++) {
var index = i;
new Thread(() -> {
lock.lock();
try {
while (true) {
System.out.println(getMessage(index));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
nextIndex = (nextIndex + 1) % THREADS;
conditions[nextIndex].signal();
while (nextIndex != index) {
conditions[index].awaitUninterruptibly();
}
}
} finally {
lock.unlock();
}
}).start();
if (index < THREADS - 1) {
lock.lock();
try {
while (nextIndex != (index + 1)) {
conditions[index + 1].awaitUninterruptibly();
}
} finally {
lock.unlock();
}
}
}
}
}
Here, we're effectively making round-robin output.
Each instance of the PingPongThread
is synchronising on itself and not on a shared resource. In order to control the message passing you'll need to synchronise on a shared resource (e.g. your turn
variable ?)
However I don't think this is really going to work. I think you should check out wait()
and notify()
to do this (if you want to understand the threading primitives). See this for an example.