[concurrency-interest] ArrayBlockingQueue (and possibly others) not waking on interrupt?

Dawid Weiss dawid.weiss at gmail.com
Tue Dec 2 03:03:10 EST 2014


Allowing myself to CC Aleksey since all the suggestions in this
discussion would constitute a very interesting (and non-trivial?) use
case example for JMH....

Dawid

On Tue, Dec 2, 2014 at 1:45 AM, Charles Oliver Nutter
<headius at headius.com> wrote:
> On Mon, Dec 1, 2014 at 5:23 PM, Josh Humphries <jh at squareup.com> wrote:
>> A future probably won't do since it's single use, but for this case, control
>> needs to keep swapping between consumer and co-routine and back. I wonder if
>> a there's a way to get a Phaser to work (plus a volatile field to actually
>> store the item being transferred).
>
> Right, future is one-shot and I need this to be a generator.
>
> I tried to think through Phaser but at the time I could not use it
> without introducing an additional library dependency.
>
>> I've actually toyed with exactly this sort of thing, emulating
>> generators/co-routines in Java using multiple threads. My experiments used a
>> SynchronousQueue, and it was painfully slow.
>
> My experience as well. It was better than Exchanger, but not by much.
> ABQ was *much* faster.
>
>> BTW, it seems like one issue
>> with ArrayBlockingQueue(1) is that it's not a perfect exchange. You can have
>> a single element in the queue, unconsumed, instead of a synchronous
>> hand-off. I think that means that the generator thread is always one ahead
>> of the consumer thread. (Although maybe I'm imagining the rest of your
>> implementation incorrectly. And perhaps this fact doesn't strictly matter.)
>
> Every fiber round-trip involves two queues (basically, every
> transferrable entity has their own queue). The calling thread triggers
> the receiving thread by feeding it the next value via the receiving
> thread's queue (Fiber#resume in Ruby). It then waits on its own queue
> for a response. This allows one-to-one round trips as well as fiber
> "transfers" where a chain of them call each other, eventually ending
> up back at the initiator.
>
> I think I'll dig up my park/unpark-based impl and give it another
> shot. It works basically like you describe, with a volatile transfer
> field and explicit parking/unparking. I agree it will probably be the
> fastest option, if I can get it to play nicely with some other Ruby
> threading oddities (Thread#kill, Thread#raise... sigh).
>
> - Charlie
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


More information about the Concurrency-interest mailing list