14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.lang;
26
27 import java.lang.Thread.Builder.OfPlatform;
28 import java.lang.Thread.Builder.OfVirtual;
29 import java.lang.Thread.UncaughtExceptionHandler;
30 import java.lang.invoke.MethodHandles;
31 import java.lang.invoke.VarHandle;
32 import java.util.Locale;
33 import java.util.Objects;
34 import java.util.concurrent.Executor;
35 import java.util.concurrent.ThreadFactory;
36 import jdk.internal.misc.Unsafe;
37 import jdk.internal.invoke.MhUtil;
38 import jdk.internal.vm.ContinuationSupport;
39
40 /**
41 * Defines static methods to create platform and virtual thread builders.
42 */
43 class ThreadBuilders {
44 private ThreadBuilders() { }
45
46 /**
47 * Base class for Thread.Builder implementations.
48 */
49 private static class BaseThreadBuilder {
50 private String name;
51 private long counter;
52 private int characteristics;
53 private UncaughtExceptionHandler uhe;
54
185 if (priority != 0)
186 thread.priority(priority);
187 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
188 if (uhe != null)
189 thread.uncaughtExceptionHandler(uhe);
190 return thread;
191 }
192
193 @Override
194 public Thread start(Runnable task) {
195 Thread thread = unstarted(task);
196 thread.start();
197 return thread;
198 }
199
200 @Override
201 public ThreadFactory factory() {
202 return new PlatformThreadFactory(group, name(), counter(), characteristics(),
203 daemonChanged, daemon, priority, stackSize, uncaughtExceptionHandler());
204 }
205
206 }
207
208 /**
209 * ThreadBuilder.OfVirtual implementation.
210 */
211 static final class VirtualThreadBuilder
212 extends BaseThreadBuilder implements OfVirtual {
213 private Executor scheduler;
214
215 VirtualThreadBuilder() {
216 }
217
218 // invoked by tests
219 VirtualThreadBuilder(Executor scheduler) {
220 if (!ContinuationSupport.isSupported())
221 throw new UnsupportedOperationException();
222 this.scheduler = Objects.requireNonNull(scheduler);
223 }
224
225 @Override
226 public OfVirtual name(String name) {
227 setName(name);
228 return this;
229 }
230
231 @Override
232 public OfVirtual name(String prefix, long start) {
233 setName(prefix, start);
234 return this;
235 }
236
237 @Override
238 public OfVirtual inheritInheritableThreadLocals(boolean inherit) {
239 setInheritInheritableThreadLocals(inherit);
240 return this;
241 }
242
243 @Override
244 public OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh) {
245 setUncaughtExceptionHandler(ueh);
246 return this;
247 }
248
249 @Override
250 public Thread unstarted(Runnable task) {
251 Objects.requireNonNull(task);
252 var thread = newVirtualThread(scheduler, nextThreadName(), characteristics(), task);
253 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
254 if (uhe != null)
255 thread.uncaughtExceptionHandler(uhe);
256 return thread;
257 }
258
259 @Override
260 public Thread start(Runnable task) {
261 Thread thread = unstarted(task);
262 thread.start();
263 return thread;
264 }
265
266 @Override
267 public ThreadFactory factory() {
268 return new VirtualThreadFactory(scheduler, name(), counter(), characteristics(),
269 uncaughtExceptionHandler());
270 }
271 }
272
273 /**
274 * Base ThreadFactory implementation.
275 */
276 private abstract static class BaseThreadFactory implements ThreadFactory {
277 private static final VarHandle COUNT = MhUtil.findVarHandle(
278 MethodHandles.lookup(), "count", long.class);
352 @Override
353 public Thread newThread(Runnable task) {
354 Objects.requireNonNull(task);
355 String name = nextThreadName();
356 Thread thread = new Thread(group, name, characteristics(), task, stackSize);
357 if (daemonChanged)
358 thread.daemon(daemon);
359 if (priority != 0)
360 thread.priority(priority);
361 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
362 if (uhe != null)
363 thread.uncaughtExceptionHandler(uhe);
364 return thread;
365 }
366 }
367
368 /**
369 * ThreadFactory for virtual threads.
370 */
371 private static class VirtualThreadFactory extends BaseThreadFactory {
372 private final Executor scheduler;
373
374 VirtualThreadFactory(Executor scheduler,
375 String name,
376 long start,
377 int characteristics,
378 UncaughtExceptionHandler uhe) {
379 super(name, start, characteristics, uhe);
380 this.scheduler = scheduler;
381 }
382
383 @Override
384 public Thread newThread(Runnable task) {
385 Objects.requireNonNull(task);
386 String name = nextThreadName();
387 Thread thread = newVirtualThread(scheduler, name, characteristics(), task);
388 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
389 if (uhe != null)
390 thread.uncaughtExceptionHandler(uhe);
391 return thread;
392 }
393 }
394
395 /**
396 * Creates a new virtual thread to run the given task.
397 */
398 static Thread newVirtualThread(Executor scheduler,
399 String name,
400 int characteristics,
401 Runnable task) {
402 if (ContinuationSupport.isSupported()) {
403 return new VirtualThread(scheduler, name, characteristics, task);
404 } else {
405 if (scheduler != null)
406 throw new UnsupportedOperationException();
407 return new BoundVirtualThread(name, characteristics, task);
408 }
409 }
410
411 /**
412 * A "virtual thread" that is backed by a platform thread. This implementation
413 * is intended for platforms that don't have the underlying VM support for
414 * continuations. It can also be used for testing.
415 */
416 static final class BoundVirtualThread extends BaseVirtualThread {
417 private static final Unsafe U = Unsafe.getUnsafe();
418 private final Runnable task;
419 private boolean runInvoked;
420
421 BoundVirtualThread(String name, int characteristics, Runnable task) {
422 super(name, characteristics, true);
423 this.task = task;
424 }
425
426 @Override
427 public void run() {
428 // run is specified to do nothing when Thread is a virtual thread
429 if (Thread.currentThread() == this && !runInvoked) {
430 runInvoked = true;
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.lang;
26
27 import java.lang.Thread.Builder.OfPlatform;
28 import java.lang.Thread.Builder.OfVirtual;
29 import java.lang.Thread.UncaughtExceptionHandler;
30 import java.lang.invoke.MethodHandles;
31 import java.lang.invoke.VarHandle;
32 import java.util.Locale;
33 import java.util.Objects;
34 import java.util.concurrent.ThreadFactory;
35 import jdk.internal.misc.Unsafe;
36 import jdk.internal.invoke.MhUtil;
37 import jdk.internal.vm.ContinuationSupport;
38
39 /**
40 * Defines static methods to create platform and virtual thread builders.
41 */
42 class ThreadBuilders {
43 private ThreadBuilders() { }
44
45 /**
46 * Base class for Thread.Builder implementations.
47 */
48 private static class BaseThreadBuilder {
49 private String name;
50 private long counter;
51 private int characteristics;
52 private UncaughtExceptionHandler uhe;
53
184 if (priority != 0)
185 thread.priority(priority);
186 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
187 if (uhe != null)
188 thread.uncaughtExceptionHandler(uhe);
189 return thread;
190 }
191
192 @Override
193 public Thread start(Runnable task) {
194 Thread thread = unstarted(task);
195 thread.start();
196 return thread;
197 }
198
199 @Override
200 public ThreadFactory factory() {
201 return new PlatformThreadFactory(group, name(), counter(), characteristics(),
202 daemonChanged, daemon, priority, stackSize, uncaughtExceptionHandler());
203 }
204 }
205
206 /**
207 * ThreadBuilder.OfVirtual implementation.
208 */
209 static final class VirtualThreadBuilder
210 extends BaseThreadBuilder implements OfVirtual {
211 private Thread.VirtualThreadScheduler scheduler;
212
213 VirtualThreadBuilder() {
214 }
215
216 @Override
217 public OfVirtual name(String name) {
218 setName(name);
219 return this;
220 }
221
222 @Override
223 public OfVirtual name(String prefix, long start) {
224 setName(prefix, start);
225 return this;
226 }
227
228 @Override
229 public OfVirtual inheritInheritableThreadLocals(boolean inherit) {
230 setInheritInheritableThreadLocals(inherit);
231 return this;
232 }
233
234 @Override
235 public OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh) {
236 setUncaughtExceptionHandler(ueh);
237 return this;
238 }
239
240 Thread unstarted(Runnable task, Thread preferredCarrier) {
241 Objects.requireNonNull(task);
242 var thread = newVirtualThread(scheduler,
243 preferredCarrier,
244 nextThreadName(),
245 characteristics(),
246 task);
247 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
248 if (uhe != null)
249 thread.uncaughtExceptionHandler(uhe);
250 return thread;
251 }
252
253 @Override
254 public Thread unstarted(Runnable task) {
255 return unstarted(task, null);
256 }
257
258 @Override
259 public Thread start(Runnable task) {
260 Thread thread = unstarted(task);
261 thread.start();
262 return thread;
263 }
264
265 @Override
266 public ThreadFactory factory() {
267 return new VirtualThreadFactory(scheduler, name(), counter(), characteristics(),
268 uncaughtExceptionHandler());
269 }
270 }
271
272 /**
273 * Base ThreadFactory implementation.
274 */
275 private abstract static class BaseThreadFactory implements ThreadFactory {
276 private static final VarHandle COUNT = MhUtil.findVarHandle(
277 MethodHandles.lookup(), "count", long.class);
351 @Override
352 public Thread newThread(Runnable task) {
353 Objects.requireNonNull(task);
354 String name = nextThreadName();
355 Thread thread = new Thread(group, name, characteristics(), task, stackSize);
356 if (daemonChanged)
357 thread.daemon(daemon);
358 if (priority != 0)
359 thread.priority(priority);
360 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
361 if (uhe != null)
362 thread.uncaughtExceptionHandler(uhe);
363 return thread;
364 }
365 }
366
367 /**
368 * ThreadFactory for virtual threads.
369 */
370 private static class VirtualThreadFactory extends BaseThreadFactory {
371 private final Thread.VirtualThreadScheduler scheduler;
372
373 VirtualThreadFactory(Thread.VirtualThreadScheduler scheduler,
374 String name,
375 long start,
376 int characteristics,
377 UncaughtExceptionHandler uhe) {
378 super(name, start, characteristics, uhe);
379 this.scheduler = scheduler;
380 }
381
382 @Override
383 public Thread newThread(Runnable task) {
384 Objects.requireNonNull(task);
385 String name = nextThreadName();
386 Thread thread = newVirtualThread(scheduler, null, name, characteristics(), task);
387 UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
388 if (uhe != null)
389 thread.uncaughtExceptionHandler(uhe);
390 return thread;
391 }
392 }
393
394 /**
395 * Creates a new virtual thread to run the given task.
396 */
397 private static Thread newVirtualThread(Thread.VirtualThreadScheduler scheduler,
398 Thread preferredCarrier,
399 String name,
400 int characteristics,
401 Runnable task) {
402 if (ContinuationSupport.isSupported()) {
403 return new VirtualThread(scheduler, preferredCarrier, name, characteristics, task);
404 } else {
405 if (scheduler != null)
406 throw new UnsupportedOperationException();
407 return new BoundVirtualThread(name, characteristics, task);
408 }
409 }
410
411 static Thread newVirtualThread(String name, int characteristics, Runnable task) {
412 return newVirtualThread(null, null, name, characteristics, task);
413 }
414
415 /**
416 * A "virtual thread" that is backed by a platform thread. This implementation
417 * is intended for platforms that don't have the underlying VM support for
418 * continuations. It can also be used for testing.
419 */
420 static final class BoundVirtualThread extends BaseVirtualThread {
421 private static final Unsafe U = Unsafe.getUnsafe();
422 private final Runnable task;
423 private boolean runInvoked;
424
425 BoundVirtualThread(String name, int characteristics, Runnable task) {
426 super(name, characteristics, true);
427 this.task = task;
428 }
429
430 @Override
431 public void run() {
432 // run is specified to do nothing when Thread is a virtual thread
433 if (Thread.currentThread() == this && !runInvoked) {
434 runInvoked = true;
|