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

Charles Oliver Nutter headius at headius.com
Mon Dec 1 15:17:53 EST 2014


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.


More information about the Concurrency-interest mailing list