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

Charles Oliver Nutter headius at headius.com
Mon Dec 1 17:34:46 EST 2014


Ahh yes, that's another one I tried. Sadly it was *also* still slower
than using a single-element ArrayBlockingQueue.

I will try to explore the options again and report back, so I know
I've got my facts straight.

- Charlie

On Mon, Dec 1, 2014 at 3:02 PM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
> Have you tried SynchronousQueue for the handoff?
>
> On Mon, Dec 1, 2014 at 3:17 PM, Charles Oliver Nutter <headius at headius.com>
> wrote:
>>
>> Sense and sanity prevail! Given the new information that this is
>> probably my fault, I dug a bit deeper...and found a race within my own
>> code. The thread interrupt logic in JRuby was firing before an
>> unblocker function was installed, causing the interrupt to just set
>> flags and not forcibly interrupt the thread. The blocking call then
>> proceeded and the flags were not checked again until after it had
>> completed. Fixed it by adding a second flag check *after* the
>> unblocker has been set but *before* making the blocking call, and it
>> seems solid now.
>>
>> Incidentally, I have a question...
>>
>> This logic is being used to emulate fibers (coroutines) in JRuby. A
>> fiber belongs to a given thread, and there may be many active fibers
>> within a thread, but none of them run concurrently. Every transfer
>> into a fiber is an explicit hand-off. If you're familiar with Python
>> generators or Go's goroutines, you get the idea. I've struggled to
>> find the right data structure to efficiently implement this hand-off.
>>
>> * Exchanger was just about the slowest way. I never figured out why.
>> * Manually implementing it with park/unpark worked, but I could never
>> get it perfect. Might have been this race or another race, so I may
>> revisit.
>> * new ArrayBlockingQueue(1) ultimately ended up being the fastest by a
>> wide margin.
>>
>> I believe I've asked this before, but what's the fastest way to
>> *explicitly* transfer control to another thread in an interruptible
>> way?
>>
>> Thanks for clarifying things :-)
>>
>> - Charlie
>>
>> On Mon, Dec 1, 2014 at 2:02 PM, Martin Buchholz <martinrb at google.com>
>> wrote:
>> > On Mon, Dec 1, 2014 at 11:50 AM, Charles Oliver Nutter
>> > <headius at headius.com> wrote:
>> >> I'm working to narrow that down now. You're right...I don't expect to
>> >> have found a bug, but I'm having trouble explaining the behavior I'm
>> >> seeing.
>> >>
>> >> Just to clarify the key point, though: LockSupport.park should be 100%
>> >> wakeable using Thread#interrupt, yes? There's no situation where a
>> >> thread in park would *not* be expected to wake up in response to
>> >> Thread#interrupt?
>> >
>> > Right - park() is allowed to return spuriously, but not allowed to
>> > spuriously fail to return !
>> > But these methods are usually called in a loop, and if a caller failed
>> > to check or notice the interrupt then it would call park again.
>> _______________________________________________
>> 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