Thread-local and concurrent contexts can nearly reclaim thread locals.

Java unfortunately offers no official way to clean up thread locals
without having each thread that owns a copy execute `remove()`.  When
JRuby is embedded in an application as a plugin in a larger system,
this can be hard or impossible to arrange.  In this scenario
`ConcurrentLocalContextProvider` and `ThreadSafeLocalContextProvider`
are basically forced to leak their thread locals.

However, this does not mean they must leak the referenced
`LocalContext` objects.  If those could be reclaimed, then the lion's
share of resources would be garbage-collectable, even if the thread
locals themselves leak.  Importantly, this would also allow the
relevant jruby classloader to be collected to enable hot-unloading in
embedding/plugin scenarios.

By wrapping each `LocalContext` in an explicit, mutable reference and
tracking those references, the providers can still make the contexts
unreachable without the help of other threads.  This is what we do
here.

In each provider:
* `ThreadLocal<LocalContext>` becomes
`ThreadLocal<AtomicReference<LocalContext>>`
* A `volatile`
`ConcurrentLinkedQueue<WeakReference<AtomicReference<LocalContext>>>`
is added to accumulate new `AtomicReference<LocalContext>` instances
as they are created
* `terminate()` walks this collection, cleaning up each context and
setting its owning `AtomicReference` value to `null`.

The `volatile`, combined with setting the container to null, takes
care of a race condition between `initialValue()` and `terminate()`.
Weak references are used to prevent the collection from accumulating
`LocalContext`s after the owning threads die.