SynchronousQueue

Volkan Yazıcı volkan.yazici at gmail.com
Sun Feb 10 19:32:26 UTC 2019


Hey Arek,

About your 2nd question, the lock is still held after yielding:

public static void main(String[] args) {
    ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    Lock writeLock = readWriteLock.writeLock();
    ContinuationScope scope = new ContinuationScope("test");
    Continuation continuation = new Continuation(scope, () -> {
        System.out.println("locking");
        writeLock.lock();
        try {
            System.out.println("locked, yielding");
            Continuation.yield(scope);
            System.out.println("resuming");
        } finally {
            System.out.println("unlocking");
            writeLock.unlock();
        }
    });
    do {
        System.out.format("locked? %s%n", readWriteLock.isWriteLocked());
        continuation.run();
    } while (!continuation.isDone());
    System.out.format("locked? %s%n", readWriteLock.isWriteLocked());
}

produces:

locked? false
locking
locked, yielding
locked? true
resuming
unlocking
locked? false

Hope this helps.

Best.


On Sun, Feb 10, 2019 at 7:07 PM Arkadiusz Gasiński <jigga at jigga.pl> wrote:

> Thank you for the clarification. After switching to "traditional" threads
> and cachedThreadPool, the output was pretty much the same as with
> singleThreadedExecutor and fibers, so it's definitely the trace messages
> that caused confusion here.
>
> (On a side point, I regret using SQ in the demo as it's not really
> > suited for fibers at this time. It's really good for transfers between
> > threads where there is a lot of contention of course. TBD on what should
> > be done for fibers in this area).
>
>
> I personally liked that example in that it clearly showed the idea behind
> fibers, i.e. yielding/freeing up carrier thread when it cannot make
> progress, which was apparent with the singleThreadedExecutor. But would be
> more than happy to find out what would you replace the SQ example with? I'm
> actually doing a workshop about project loom for my coworkers next week. I
> know it's still a prototype, and a lot may change before it's released, but
> it's really interesting project and current version is stable enough to
> play with it and explore the possibilities it may/will bring to the
> platform. The main theme of the workshop will be to reconfigure sample
> Spring Boot microservice to use Fibers instead of Threads as we work with
> Boot on the daily basis, but if you think that there is anything in
> particular that I should touch on when doing this workshop, I'd be thankful
> for suggestions.
>
> One last thing...
>
> continuation = new Continuation(scope, () -> {
>     var lock = new ReentrantReadWriteLock();
>     lock.readLock().lock();
>     try {
>         System.out.println(1);
>         Continuation.yield(scope);
>         System.out.println(2);
>     } finally {
>         lock.readLock().unlock();
>     }
> });
>
>
> It's possible to yield a continuation when holding a
> j.u.c.l.Lock/ReadWriteLock. It this lock released when yielding and somehow
> reacquired when continuing?
>
> Thanks,
> Arek
>
> On Sun, Feb 10, 2019 at 10:53 AM Alan Bateman <Alan.Bateman at oracle.com>
> wrote:
>
> > On 09/02/2019 12:33, Arkadiusz Gasiński wrote:
> > > :
> > > I assumed (as SynchronousQueue has no capacity) that the output would
> be
> > > more like:
> > >
> > > Produder.offer
> > > Consumer.take
> > > Producer.offer
> > > Consumer.tak
> > >
> > > And so on. But in the actual output almost each time 2 tasks are
> actually
> > > offered and then 2 tasks are taken. Do you have any idea why this
> > happens?
> > I briefly looked at your test and the producer and consumer (sharing one
> > thread) are running in lockstep, I think it's just the trace messages
> > that are a bit misleading. The producer prints the "Offering" message
> > before queue.put. The put doesn't need to block/park when the consumer
> > is parked/waiting for an element N so it will continue on and print
> > "Offering" message for element N+1 before it blocks/parks in queue.put.
> > On the consumer side, it prints "Processing" after queue.take has been
> > used to remove element N. The producer offering element N+1 has released
> > the thread to allow the consumer to continue so it will process element
> > N and continue to take element N+1. If you update the test to print a
> > trace message before and after both queue.put and queue.take then I
> > think it will be a bit clearer.
> >
> > (On a side point, I regret using SQ in the demo as it's not really
> > suited for fibers at this time. It's really good for transfers between
> > threads where there is a lot of contention of course. TBD on what should
> > be done for fibers in this area).
> >
> > -Alan
> >
> >
> >
> >
> >
> >
>


More information about the loom-dev mailing list