A lightweight thread is a Thread
Andrew Haley
aph at redhat.com
Wed Oct 23 17:38:28 UTC 2019
On 10/23/19 1:49 PM, David Lloyd wrote:
> On Wed, Oct 23, 2019 at 3:59 AM Andrew Haley <aph at redhat.com> wrote:
>>
>> On 10/22/19 5:27 PM, David Lloyd wrote:
>>> One would still have to allow subclassing of threads though IMO, even
>>> in the lightweight case. This is enormously useful
>>
>> What is it about subclassing Thread that is enormously useful? I can't
>> immediately think of any case where a scoped local couldn't achieve the
>> same thing. Instead of
>>
>> (MyFoo)Thread.current();
>>
>> you'd have
>>
>> CurrentFoo.get();
>>
>> ... which would work in lightweight and heavyweight Threads. Is there
>> something that definitely wouldn't work with this mechanism?
>
> Apart from being the fastest possible way to have thread local values
> in Java,
I don't think you'd notice any difference:
Benchmark Mode Cnt Score Error Units
ThreadLocalTest.getFieldFromLocal avgt 3 1.728 ± 0.018 ns/op
ThreadLocalTest.getFieldFromThread avgt 3 1.439 ± 0.003 ns/op
@Benchmark
public void getFieldFromLocal(MyState state) {
Sink.getSink().drain(BenchmarkState.myScoped7.get());
}
@Benchmark
public void getFieldFromThread(MyState state) {
Sink.getSink().drain(((MyThread)Thread.currentThread()).userObjectField);
}
That's 6 clock cycles (@ 3.5GHz) for the scoped value, 5 for the field
in Thread. Darn! :-)
In contrast, ThreadLocal:
@Benchmark
public void getFieldFromThreadLocal(MyState state) {
Sink.getSink().drain(BenchmarkState.t1.get());
}
Benchmark Mode Cnt Score Error Units
ThreadLocalTest.getFieldFromThreadLocal avgt 3 4.922 ± 2.382 ns/op
(17 clocks.)
The usual caveats: C2 heuristics can completely mess this up, so YMMV.
Benchmarking such extremely narrow intervals of time is very tricky,
even with JMH. This is a Threadripper 2950X and I think its L1 cache
latency is 5 clocks.
> there are a couple things we can only do by subclassing Thread. In
> JBoss EAP and WildFly, we support custom interrupt handlers (this is
> something that is in the JDK but is not public, thus subclassing
> Thread is the only way to do it) and interrupt deferral (only Thread
> subclasses can do this).
I don't know how much of this will be supported by lightweight
threads. I could guess but I'll leave that to the people involved.
> Vert.x/Netty uses a custom thread subclass to support "faster"
> thread locals (though looking at the code I suspect these "faster"
> thread locals might be heavier than the JDK's thread local support).
@Benchmark
public void getFieldFromFastThreadLocal(MyState state) {
Sink.getSink().drain(BenchmarkState.f1.get());
}
Benchmark Mode Cnt Score Error Units
ThreadLocalTest.getFieldFromFastThreadLocal avgt 3 2.287 ± 0.063 ns/op
10 clocks. That's actually pretty damned good considering they
didn't touch the JVM. There is the trade-off, though, that every
thread that uses this has a fixed-size array of thread locals at least
as large as the highest-numbered FastThreadLocal it uses.
It's a really sweet idea, but I'm not sure I could get away with it
in a general-purpose facility because of scaling issues. Food for
thought...
> Sometimes you want to be able to do `ThreadSubclass foo =
> notCurrentThread(); foo.something();`. From what I understand, one
> can't easily get a scoped local for some other thread.
True. Apart from any other issues I don't do anything thread-safe. TBH
I'm not sure if this is safe for ThreadLocal either, unless they are
very careful about concurrent access to the pool of ThreadLocals.
> We also use it for user-supplied thread shutdown hooks, but of course
> that can also be done by wrapping the Runnable (via ThreadFactory for
> instance).
>
> I did a search in my IDE's Quarkus code base and in the JDK and
> supporting projects, there are presently 374 Thread subclasses. I'm
> not sure what percentage of those really *needs* to be an actual
> subclass though. Most of the JDK cases (based on a random sampling)
> appear to just override the `run()` method and probably carry over (at
> least stylewise) from a very old JDK.
Yes, I'd guess so.
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the loom-dev
mailing list