< prev index next >

src/java.base/share/classes/java/lang/ThreadBuilders.java

Print this page

 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 
 55         String name() {
 56             return name;
 57         }

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);
279 
280         private final String name;
281         private final int characteristics;
282         private final UncaughtExceptionHandler uhe;
283 
284         private final boolean hasCounter;
285         private volatile long count;
286 
287         BaseThreadFactory(String name,
288                           long start,
289                           int characteristics,
290                           UncaughtExceptionHandler uhe)  {

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.reflect.CallerSensitive;
 38 import jdk.internal.reflect.Reflection;
 39 import jdk.internal.vm.ContinuationSupport;
 40 
 41 /**
 42  * Defines static methods to create platform and virtual thread builders.
 43  */
 44 class ThreadBuilders {
 45     private ThreadBuilders() { }
 46 
 47     /**
 48      * Base class for Thread.Builder implementations.
 49      */
 50     private static class BaseThreadBuilder {
 51         private String name;
 52         private long counter;
 53         private int characteristics;
 54         private UncaughtExceptionHandler uhe;
 55 
 56         String name() {
 57             return name;
 58         }

186             if (priority != 0)
187                 thread.priority(priority);
188             UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
189             if (uhe != null)
190                 thread.uncaughtExceptionHandler(uhe);
191             return thread;
192         }
193 
194         @Override
195         public Thread start(Runnable task) {
196             Thread thread = unstarted(task);
197             thread.start();
198             return thread;
199         }
200 
201         @Override
202         public ThreadFactory factory() {
203             return new PlatformThreadFactory(group, name(), counter(), characteristics(),
204                     daemonChanged, daemon, priority, stackSize, uncaughtExceptionHandler());
205         }

206     }
207 
208     /**
209      * ThreadBuilder.OfVirtual implementation.
210      */
211     static final class VirtualThreadBuilder
212             extends BaseThreadBuilder implements OfVirtual {
213         private Thread.VirtualThreadScheduler scheduler;
214 
215         VirtualThreadBuilder() {
216         }
217 







218         @Override
219         public OfVirtual name(String name) {
220             setName(name);
221             return this;
222         }
223 
224         @Override
225         public OfVirtual name(String prefix, long start) {
226             setName(prefix, start);
227             return this;
228         }
229 
230         @Override
231         public OfVirtual inheritInheritableThreadLocals(boolean inherit) {
232             setInheritInheritableThreadLocals(inherit);
233             return this;
234         }
235 
236         @Override
237         public OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh) {
238             setUncaughtExceptionHandler(ueh);
239             return this;
240         }
241 
242         @Override
243         public Thread unstarted(Runnable task) {
244             Objects.requireNonNull(task);
245             var thread = newVirtualThread(scheduler,
246                                           null,
247                                           nextThreadName(),
248                                           characteristics(),
249                                           task,
250                                           null);
251             UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
252             if (uhe != null)
253                 thread.uncaughtExceptionHandler(uhe);
254             return thread;
255         }
256 
257         @Override
258         public Thread start(Runnable task) {
259             Thread thread = unstarted(task);
260             thread.start();
261             return thread;
262         }
263 
264         @Override
265         public ThreadFactory factory() {
266             return new VirtualThreadFactory(scheduler, name(), counter(), characteristics(),
267                     uncaughtExceptionHandler());
268         }
269 
270         @CallerSensitive
271         @Override
272         public Thread unstarted(Runnable task, Thread preferredCarrier, Object att) {
273             Objects.requireNonNull(task);
274             Class<?> caller = Reflection.getCallerClass();
275             caller.getModule().ensureNativeAccess(OfVirtual.class, "unstarted", caller, false);
276             var thread = newVirtualThread(scheduler,
277                                           preferredCarrier,
278                                           nextThreadName(),
279                                           characteristics(),
280                                           task,
281                                           att);
282             UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
283             if (uhe != null)
284                 thread.uncaughtExceptionHandler(uhe);
285             return thread;
286         }
287 
288         @CallerSensitive
289         @Override
290         public OfVirtual scheduler(Thread.VirtualThreadScheduler scheduler) {
291             if (!ContinuationSupport.isSupported()) {
292                 throw new UnsupportedOperationException();
293             }
294             // can't mix custom default scheduler and API prototypes at this time
295             if (scheduler != VirtualThread.defaultScheduler()
296                     && VirtualThread.defaultScheduler() != VirtualThread.builtinScheduler()) {
297                 throw new UnsupportedOperationException();
298             }
299             Class<?> caller = Reflection.getCallerClass();
300             caller.getModule().ensureNativeAccess(OfVirtual.class, "scheduler", caller, false);
301             this.scheduler = Objects.requireNonNull(scheduler);
302             return this;
303         }
304     }
305 
306     /**
307      * Base ThreadFactory implementation.
308      */
309     private abstract static class BaseThreadFactory implements ThreadFactory {
310         private static final VarHandle COUNT = MhUtil.findVarHandle(
311                 MethodHandles.lookup(), "count", long.class);
312 
313         private final String name;
314         private final int characteristics;
315         private final UncaughtExceptionHandler uhe;
316 
317         private final boolean hasCounter;
318         private volatile long count;
319 
320         BaseThreadFactory(String name,
321                           long start,
322                           int characteristics,
323                           UncaughtExceptionHandler uhe)  {

385         @Override
386         public Thread newThread(Runnable task) {
387             Objects.requireNonNull(task);
388             String name = nextThreadName();
389             Thread thread = new Thread(group, name, characteristics(), task, stackSize);
390             if (daemonChanged)
391                 thread.daemon(daemon);
392             if (priority != 0)
393                 thread.priority(priority);
394             UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
395             if (uhe != null)
396                 thread.uncaughtExceptionHandler(uhe);
397             return thread;
398         }
399     }
400 
401     /**
402      * ThreadFactory for virtual threads.
403      */
404     private static class VirtualThreadFactory extends BaseThreadFactory {
405         private final Thread.VirtualThreadScheduler scheduler;
406 
407         VirtualThreadFactory(Thread.VirtualThreadScheduler scheduler,
408                              String name,
409                              long start,
410                              int characteristics,
411                              UncaughtExceptionHandler uhe) {
412             super(name, start, characteristics, uhe);
413             this.scheduler = scheduler;
414         }
415 
416         @Override
417         public Thread newThread(Runnable task) {
418             Objects.requireNonNull(task);
419             String name = nextThreadName();
420             Thread thread = newVirtualThread(scheduler, null, name, characteristics(), task, null);
421             UncaughtExceptionHandler uhe = uncaughtExceptionHandler();
422             if (uhe != null)
423                 thread.uncaughtExceptionHandler(uhe);
424             return thread;
425         }
426     }
427 
428     /**
429      * Creates a new virtual thread to run the given task.
430      */
431     private static Thread newVirtualThread(Thread.VirtualThreadScheduler scheduler,
432                                            Thread preferredCarrier,
433                                            String name,
434                                            int characteristics,
435                                            Runnable task,
436                                            Object att) {
437         if (ContinuationSupport.isSupported()) {
438             return new VirtualThread(scheduler, preferredCarrier, name, characteristics, task, att);
439         } else {
440             if (scheduler != null)
441                 throw new UnsupportedOperationException();
442             return new BoundVirtualThread(name, characteristics, task);
443         }
444     }
445 
446     static Thread newVirtualThread(String name, int characteristics, Runnable task) {
447        return newVirtualThread(null, null, name, characteristics, task, null);
448     }
449 
450     /**
451      * A "virtual thread" that is backed by a platform thread. This implementation
452      * is intended for platforms that don't have the underlying VM support for
453      * continuations. It can also be used for testing.
454      */
455     static final class BoundVirtualThread extends BaseVirtualThread {
456         private static final Unsafe U = Unsafe.getUnsafe();
457         private final Runnable task;
458         private boolean runInvoked;
459 
460         BoundVirtualThread(String name, int characteristics, Runnable task) {
461             super(name, characteristics, true);
462             this.task = task;
463         }
464 
465         @Override
466         public void run() {
467             // run is specified to do nothing when Thread is a virtual thread
468             if (Thread.currentThread() == this && !runInvoked) {
469                 runInvoked = true;
< prev index next >