Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

22 Commits

Repository files navigation

Simulating Continuation in Java Via Threads and Trampoline Pattern

Using Threads


Following is an example of how to use the Continuation.java. Its constructor receives a Runnable as the body of the routine that calls yield(s).
The very first goOn() call would start running the Runnable until it yields upon which the control is transferred back to the main routine where goOn() was invoked. This ping pong transfer of control between main and sub routine continues until Runnable finishes through the very last yield() call.

Continuation<Integer> cont;
...
cont = newContinuation<>(
() -> {
//Sub RoutineSystem.out.println("2:subRoutine");
cont.yield(1); //return 1System.out.println("4:subRoutine");
cont.yield(2); //return 2System.out.println("6:subRoutine");
cont.yield(3); //return 3
}
);
//Main Routineintresult;
System.out.println("1:mainRoutine");
result = cont.goOn(); //result = 1System.out.println("3:mainRoutine");
result = cont.goOn(); //result = 2System.out.println("5:mainRoutine");
result = cont.goOn(); //result = 3System.out.println("7:mainRoutine");
/* Output: 1:mainRoutine 2:subRoutine  3:mainRoutine 4:subRoutine 5:mainRoutine 6:subRoutine 7:mainRoutine*/

Generator.java utilizes Continuation.java to implement Iterable interface and act as a lazy generator. Its yield() method emits values as the Iterator asks for next value.

Note: The current Iterable and Iterator implementation is incomplete and does not comply with the specifications completely. For example it requires hasNext() method to be called before every next() call.

Bellow is an example of a generator that can emit integers starting from 0 up to Long.MAX_VALUE in a lazy way.

Generator<Long> intGenerator;
...
intGenerator = newGenerator<>(
() -> {
for(longi=0; i<Long.MAX_VALUE; i++) {
intGenerator.yield(i);
} } );
for(intj: intGenerator)
if(j <= 100) System.out.println(j);
elsebreak;

Following is the stripped down version of the Continuation.java to provide an idea on how the yield mechanism is simulated. Note that goOn() and yield() methods are being called from two different threads. using lock and conditions the class simulates the back and forth transfer of control between two different routines.

publicvoidyield(Tvalue) throwsInterruptedException {
try {
this.value = value;
lock.lock();
mainRoutineCondition.signal();
subRoutineCondition.await();
}finally {
lock.unlock();
}
}
publicTgoOn() throwsInterruptedException {
value = null;
try {
lock.lock();
if (subRoutineThread.getState() == Thread.State.NEW) {
subRoutineThread.start();
} elsesubRoutineCondition.signal();
mainRoutineCondition.await();
returnvalue;
}finally {
lock.unlock();
}
}

Using Trampoline


Continuation<Integer> myCont = newContinuation<Integer>() {
inti = -1;
@OverridepublicIntegerstart() {
i++;
if(i < 100) {
thenRun(this::next);
}
returni;
}
};
IntStream.range(0, 10000).forEach(
i -> System.out.println(myCont.goOn())
);

About

Implementing "Continuation" concepts in Java

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages