Use CyclicBarrier. Here is a quote related to her Javadok:
A synchronization assistant that allows multiple threads for all to wait for each other to reach a common barrier point. CyclicBarriers are useful in programs related to the fixed side of the parties, which must wait for each other from time to time. A barrier is called cyclic because it can be reused after waiting threads are released.
So, you need to create CyclicBarrierfor several parties 2and allow the receiver thread to call await()after the ACK and allow the sender thread await()before executing SEND.
Here is SSCCE to get you started.
package com.stackoverflow.q3379797;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2);
Receiver receiver = new Receiver(barrier);
Sender sender = new Sender(barrier);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(receiver);
executor.submit(sender);
}
}
class Receiver implements Runnable {
private CyclicBarrier barrier;
public Receiver(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
System.out.println("ACK");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Sender implements Runnable {
private CyclicBarrier barrier;
public Sender(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while (true) {
try {
barrier.await();
System.out.println("SEND");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
:
(2 seconds)
ACK
SEND
(2 seconds)
ACK
SEND
(2 seconds)
ACK
SEND