Skip to main content

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

8
  • 2
    The crucial part is the reflective construction of the thread builder. There is no need to keep using Reflection after that. There’s also no point in catching all those subclasses of ReflectiveOperationException, to wrap them in a new ReflectiveOperationException. So you can simplify it to static Thread.Builder customVirtualThreadPool(Executor executor) throws ReflectiveOperationException { var ctor = Class.forName("java.lang.ThreadBuilders$VirtualThreadBuilder").getDeclaredConstructor(Executor.class); ctor.setAccessible(true); return (Thread.Builder)ctor.newInstance(executor); } Commented Jun 7, 2024 at 8:47
  • 1
    This static method can be used together with the public API, e.g. Executor e = customVirtualThreadPool(pool)::start; or Executors.newThreadPerTaskExecutor(customVirtualThreadPool(pool).factory()) or even applying more customization: Executors.newThreadPerTaskExecutor(customVirtualThreadPool(pool) .inheritInheritableThreadLocals(false).name("my-custom-thread-", 100).factory()) Commented Jun 7, 2024 at 8:49
  • 1
    the takeaway is, since his suggested improvements were made, there is no reason left for developers to use Unsafe directly. The higher level APIs are at least on par. But it’s even possible that a future improvement will only accelerate the official API as Unsafe itself is the remaining bottleneck and the faster solution can only work without. Well, there are also practical advice you can read from his article, like storing a VarHandle in a static final field is a good idea to get maximum performance with today’s implementations. Commented Jun 10, 2024 at 7:49
  • 1
    Well, the optimized code of today is the legacy of tomorrow. The built-in classes have the advantage that they can get adapted with every Java version. If found this comment which suggests that the reason ForkJoinPool uses Unsafe in recent versions is not performance: “[…] should be using VarHandles. It was attempted for ForkJoinPool in JDK 19 but had to be reverted back to Unsafe due to bootstrapping and initialization issues… Commented Jun 11, 2024 at 9:44
  • 1
    The term “work-stealing” puts an emphasis on the wrong thing, as stealing is how all thread pools work. What sets F/J apart, is the existence of local queues in the first place, including the ability of a task to revoke a submission and execute the subtask locally, if it has not stolen yet. So you can create subtasks at a much higher granularity, to ensure saturation of worker threads even when tasks take significantly different time, without the overhead of a too large number of asynchronous tasks. A high steal count is not necessarily a good sign (but also not necessarily a bad sign). Commented Jun 12, 2024 at 8:45