Strand class & continuation example

Ron Pressler ron.pressler at oracle.com
Sat Feb 2 16:16:12 UTC 2019


 




On February 2, 2019 at 12:26:53 AM, Arkadiusz Gasiński (jigga at jigga.pl(mailto:jigga at jigga.pl)) wrote:

> Hi,  
>  
> Thanks for your answers.  
>  
> I actually rewrote the Fibonacci generator  
>  
> from Kotlin's coroutines proposal using loom's continuations:  
>  
> static class Fibonacci {  
>  
> private static final ContinuationScope scope = new  
> ContinuationScope("Fibonacci");  
> private Continuation cont;  
> private BigInteger value = BigInteger.ONE;  
>  
> public Fibonacci() {  
> cont = new Continuation(scope, () -> {  
> Continuation.yield(scope);  
> var cur = value;  
> var next = BigInteger.ONE;  
> while (true) {  
> value = next;  
> Continuation.yield(scope);  
> var tmp = cur.add(next);  
> cur = next;  
> next = tmp;  
> }  
> });  
> }  
>  
> public BigInteger getNext() {  
> cont.run();  
> return value;  
> }  
>  
> }  
>  
> Works fine, although I gotta admit that I like the Kotlin's approach better  
> in that the yield function actually returns the current (possibly partial)  
> result and with loom's continuations I need to introduce a local variable  
> (or maybe I don't?). Have you considered making the Continuation class  
> generic and changing run/yield methods return types to the continuation's  
> generic type?  

It’s not a different approach, just a higher level construct, that’s built
on top of a low level one. java.lang.Continuation is a very low-level construct.
It’s unlikely that application code would ever use it.

If we do introduce a higher level continuation that passes values,
 it will be in a Continuation subclass. For now, just subclass 
Continuation yourself and introduce a member variable to hold the yield results
(and, of course, write your own yield/run methods).


>  
>  
> Also, given the Fibonacci class above, I was a bit surprised (considering  
> my first attempts at using Continuation class) that the below code worked:  
>  
> var sequence = new Fibonacci();  
> System.out.println(sequence.getNext());  
> System.out.println(CompletableFuture.supplyAsync(() ->  
> sequence.getNext()).get());  
>  
>  
> Does that mean that I can yield a given continuation only in the same  
> thread that I've run it in?  
> 

You do not yield a continuation. A continuation yields itself,
so obviously that is done in the same thread.

Recently we’ve introduced a feature to forcefully *preempt* a continuation
from another thread.

> What about the thread safety of the Continuation class instances? 

It is thread safe in the sense that attempts to mount the same continuation
on multiple threads concurrently will throw an exception.

It is a low-level construct not intended for direct use by application code, 
so it is the responsibility of any higher-level, user-facing API (like Fiber) to 
introduce thread-safety.


>  
> Thanks,  
> Arek 

Ron

>  
> On Thu, Jan 31, 2019 at 12:36 PM Alan Bateman  
> wrote:  
>  
> > On 30/01/2019 23:37, Remi Forax wrote:  
> > > Hi !  
> > >  
> > > ----- Mail original -----  
> > >> De: "Arkadiusz Gasiński"  
> > >> À: "loom-dev"  
> > >> Envoyé: Mercredi 30 Janvier 2019 19:11:50  
> > >> Objet: Strand class & continuation example  
> > >> Hi,  
> > >>  
> > >> I assume that you're all busy with the loom project, but if anyone here  
> > >> finds some time to briefly explain the rationale behind removal of the  
> > >> Strand class, I'll be really grateful.  
> > > Ron or Alan may correct me but  
> > > the idea of a Strand was that at some point you want consider a Fiber or  
> > a Thread as a common strand, but given that their API are different, you  
> > can not do much on a strand apart asking if it's a fiber or a thread. That  
> > said, you may have a use case were a strand make sense, in that case do not  
> > hesitate to share it on this list.  
> > Right, we discussed this in October [1] when we had a super class that  
> > didn't define anything except a static method to get the current strand,  
> > essentially the same as:  
> > strand = Fiber.current().map(f ->  
> > (Object)f).orElse(Thread.currentThread());  
> >  
> > In the JDK, there are cases where the interrupt status needs to be  
> > checked and re-asserted, and of course waiter queues, where some  
> > reference is needed, but little need beyond that. So yes, if there are  
> > good use cases then it would good to bring up.  
> >  
> > -Alan  
> >  
> > [1] http://cr.openjdk.java.net/~alanb/loom/LoomMeeting20181018.pdf  
> >  
> >  



More information about the loom-dev mailing list