class Main {
public static void main(String[] args) throws Exception{
Coroutine<Integer> coroutine = new Coroutine<>(new CoroutineRunnable<Integer>() {
@Override
public void run() {
try {
System.out.println("Waiting for process 1");
coroutine.yield(5);
System.out.println("Waiting for process 2");
coroutine.yield(10);
System.out.println("Waiting for process 3");
coroutine.yield(15);
System.out.println("All done");
}
catch (Exception ex) {
}
}
});
Thread.sleep(1000);
Integer t = coroutine.process();
System.out.println(t);
Thread.sleep(1000);
t = coroutine.process();
System.out.println(t);
Thread.sleep(1000);
t = coroutine.process();
System.out.println(t);
}
}
public abstract class CoroutineRunnable<T> implements Runnable {
protected Coroutine<T> coroutine;
public void setCoroutine(Coroutine<T> coroutine) {
this.coroutine = coroutine;
}
}
import java.util.concurrent.Semaphore;
public class Coroutine<T> {
private Semaphore yieldSemaphore = new Semaphore(1);
private Semaphore processSemaphore = new Semaphore(1);
private Thread thread;
private T t;
public Coroutine(CoroutineRunnable<T> runnable) throws Exception {
yieldSemaphore.acquire();
processSemaphore.acquire();
thread = new Thread(runnable);
runnable.setCoroutine(this);
thread.start();
}
public void yield() throws Exception {
yield(null);
}
public void yield(T t) throws Exception {
this.t = t;
processSemaphore.release();
yieldSemaphore.acquire();
}
public T process() throws Exception {
processSemaphore.acquire();
T t = this.t;
yieldSemaphore.release();
return t;
}
}