< prev index next >

src/java.base/share/classes/java/lang/Thread.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 
  26 package java.lang;
  27 
  28 import java.lang.ref.Reference;
  29 import java.lang.reflect.Field;
  30 import java.time.Duration;
  31 import java.util.Map;
  32 import java.util.HashMap;
  33 import java.util.Objects;

  34 import java.util.concurrent.ThreadFactory;
  35 import java.util.concurrent.StructureViolationException;
  36 import java.util.concurrent.locks.LockSupport;
  37 import jdk.internal.event.ThreadSleepEvent;

  38 import jdk.internal.misc.TerminatingThreadLocal;
  39 import jdk.internal.misc.Unsafe;
  40 import jdk.internal.misc.VM;


  41 import jdk.internal.vm.Continuation;
  42 import jdk.internal.vm.ScopedValueContainer;
  43 import jdk.internal.vm.StackableScope;
  44 import jdk.internal.vm.ThreadContainer;
  45 import jdk.internal.vm.annotation.ForceInline;
  46 import jdk.internal.vm.annotation.Hidden;
  47 import jdk.internal.vm.annotation.IntrinsicCandidate;
  48 import jdk.internal.vm.annotation.Stable;
  49 import sun.nio.ch.Interruptible;
  50 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  51 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  52 
  53 /**
  54  * A <i>thread</i> is a thread of execution in a program. The Java
  55  * virtual machine allows an application to have multiple threads of
  56  * execution running concurrently.
  57  *
  58  * <p> {@code Thread} defines constructors and a {@link Builder} to create threads.
  59  * {@linkplain #start() Starting} a thread schedules it to execute its {@link #run() run}
  60  * method. The newly started thread executes concurrently with the thread that caused

 269 
 270     // thread name
 271     private volatile String name;
 272 
 273     // interrupted status (read/written by VM)
 274     volatile boolean interrupted;
 275 
 276     // context ClassLoader
 277     private volatile ClassLoader contextClassLoader;
 278 
 279     // Additional fields for platform threads.
 280     // All fields, except task and terminatingThreadLocals, are accessed directly by the VM.
 281     private static class FieldHolder {
 282         final ThreadGroup group;
 283         final Runnable task;
 284         final long stackSize;
 285         volatile int priority;
 286         volatile boolean daemon;
 287         volatile int threadStatus;
 288 



 289         // This map is maintained by the ThreadLocal class
 290         ThreadLocal.ThreadLocalMap terminatingThreadLocals;
 291 
 292         FieldHolder(ThreadGroup group,
 293                     Runnable task,
 294                     long stackSize,
 295                     int priority,
 296                     boolean daemon) {
 297             this.group = group;
 298             this.task = task;
 299             this.stackSize = stackSize;
 300             this.priority = priority;
 301             if (daemon)
 302                 this.daemon = true;
 303         }
 304     }
 305     private final FieldHolder holder;
 306 
 307     ThreadLocal.ThreadLocalMap terminatingThreadLocals() {
 308         return holder.terminatingThreadLocals;
 309     }
 310 
 311     void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) {
 312         holder.terminatingThreadLocals = map;
 313     }
 314 








 315     /*
 316      * ThreadLocal values pertaining to this thread. This map is maintained
 317      * by the ThreadLocal class.
 318      */
 319     private ThreadLocal.ThreadLocalMap threadLocals;
 320 
 321     ThreadLocal.ThreadLocalMap threadLocals() {
 322         return threadLocals;
 323     }
 324 
 325     void setThreadLocals(ThreadLocal.ThreadLocalMap map) {
 326         threadLocals = map;
 327     }
 328 
 329     /*
 330      * InheritableThreadLocal values pertaining to this thread. This map is
 331      * maintained by the InheritableThreadLocal class.
 332      */
 333     private ThreadLocal.ThreadLocalMap inheritableThreadLocals;
 334 

 709         static {
 710             U = Unsafe.getUnsafe();
 711             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 712         }
 713         static long next() {
 714             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 715         }
 716     }
 717 
 718     /**
 719      * Initializes a platform Thread.
 720      *
 721      * @param g the Thread group, can be null
 722      * @param name the name of the new Thread
 723      * @param characteristics thread characteristics
 724      * @param task the object whose run() method gets called
 725      * @param stackSize the desired stack size for the new thread, or
 726      *        zero to indicate that this parameter is to be ignored.
 727      */
 728     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
 729 
 730         Thread parent = currentThread();
 731         boolean attached = (parent == this);   // primordial or JNI attached
 732 
 733         if (attached) {
 734             if (g == null) {
 735                 throw new InternalError("group cannot be null when attaching");
 736             }
 737             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 738         } else {
 739             if (g == null) {
 740                 // default to current thread's group
 741                 g = parent.getThreadGroup();
 742             }
 743             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 744             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 745         }
 746 
 747         if (attached && VM.initLevel() < 1) {
 748             this.tid = PRIMORDIAL_TID;  // primordial thread
 749         } else {

 793             }
 794             this.contextClassLoader = parent.getContextClassLoader();
 795         } else {
 796             // default CCL to the system class loader when not inheriting
 797             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 798         }
 799 
 800         // special value to indicate this is a newly-created Thread
 801         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 802 
 803         // create a FieldHolder object, needed when bound to an OS thread
 804         if (bound) {
 805             ThreadGroup g = Constants.VTHREAD_GROUP;
 806             int pri = NORM_PRIORITY;
 807             this.holder = new FieldHolder(g, null, -1, pri, true);
 808         } else {
 809             this.holder = null;
 810         }
 811     }
 812 
























































































































































 813     /**
 814      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
 815      * that creates platform threads.
 816      *
 817      * @apiNote The following are examples using the builder:
 818      * {@snippet :
 819      *   // Start a daemon thread to run a task
 820      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
 821      *
 822      *   // Create an unstarted thread with name "duke", its start() method
 823      *   // must be invoked to schedule it to execute.
 824      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
 825      *
 826      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
 827      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
 828      * }
 829      *
 830      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
 831      * @since 21
 832      */

1047          * that creates virtual threads.
1048          *
1049          * <p> Unless otherwise specified, passing a null argument to a method in
1050          * this interface causes a {@code NullPointerException} to be thrown.
1051          *
1052          * @see Thread#ofVirtual()
1053          * @since 21
1054          */
1055         sealed interface OfVirtual extends Builder
1056                 permits ThreadBuilders.VirtualThreadBuilder {
1057 
1058             @Override OfVirtual name(String name);
1059 
1060             /**
1061              * @throws IllegalArgumentException {@inheritDoc}
1062              */
1063             @Override OfVirtual name(String prefix, long start);
1064 
1065             @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1066             @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);


















































1067         }
1068     }
1069 
1070     /**
1071      * Throws CloneNotSupportedException as a Thread can not be meaningfully
1072      * cloned. Construct a new Thread instead.
1073      *
1074      * @throws  CloneNotSupportedException
1075      *          always
1076      */
1077     @Override
1078     protected Object clone() throws CloneNotSupportedException {
1079         throw new CloneNotSupportedException();
1080     }
1081 
1082     /**
1083      * Helper class for auto-numbering platform threads. The numbers start at
1084      * 0 and are separate from the thread identifier for historical reasons.
1085      */
1086     private static class ThreadNumbering {

1408     public Thread(ThreadGroup group, Runnable task, String name,
1409                   long stackSize, boolean inheritInheritableThreadLocals) {
1410         this(group, checkName(name),
1411                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1412                 task, stackSize);
1413     }
1414 
1415     /**
1416      * Creates a virtual thread to execute a task and schedules it to execute.
1417      *
1418      * <p> This method is equivalent to:
1419      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1420      *
1421      * @param task the object to run when the thread executes
1422      * @return a new, and started, virtual thread
1423      * @see <a href="#inheritance">Inheritance when creating threads</a>
1424      * @since 21
1425      */
1426     public static Thread startVirtualThread(Runnable task) {
1427         Objects.requireNonNull(task);
1428         var thread = ThreadBuilders.newVirtualThread(null, null, 0, task);
1429         thread.start();
1430         return thread;
1431     }
1432 
1433     /**
1434      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1435      * is scheduled by the Java virtual machine rather than the operating system.
1436      *
1437      * @return {@code true} if this thread is a virtual thread
1438      *
1439      * @since 21
1440      */
1441     public final boolean isVirtual() {
1442         return (this instanceof BaseVirtualThread);
1443     }
1444 
1445     /**
1446      * Schedules this thread to begin execution. The thread will execute
1447      * independently of the current thread.
1448      *

  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 
  26 package java.lang;
  27 
  28 import java.lang.ref.Reference;
  29 import java.lang.reflect.Field;
  30 import java.time.Duration;
  31 import java.util.Map;
  32 import java.util.HashMap;
  33 import java.util.Objects;
  34 import java.util.concurrent.RejectedExecutionException;
  35 import java.util.concurrent.ThreadFactory;
  36 import java.util.concurrent.StructureViolationException;
  37 import java.util.concurrent.locks.LockSupport;
  38 import jdk.internal.event.ThreadSleepEvent;
  39 import jdk.internal.javac.Restricted;
  40 import jdk.internal.misc.TerminatingThreadLocal;
  41 import jdk.internal.misc.Unsafe;
  42 import jdk.internal.misc.VM;
  43 import jdk.internal.reflect.CallerSensitive;
  44 import jdk.internal.reflect.Reflection;
  45 import jdk.internal.vm.Continuation;
  46 import jdk.internal.vm.ScopedValueContainer;
  47 import jdk.internal.vm.StackableScope;
  48 import jdk.internal.vm.ThreadContainer;
  49 import jdk.internal.vm.annotation.ForceInline;
  50 import jdk.internal.vm.annotation.Hidden;
  51 import jdk.internal.vm.annotation.IntrinsicCandidate;
  52 import jdk.internal.vm.annotation.Stable;
  53 import sun.nio.ch.Interruptible;
  54 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  55 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  56 
  57 /**
  58  * A <i>thread</i> is a thread of execution in a program. The Java
  59  * virtual machine allows an application to have multiple threads of
  60  * execution running concurrently.
  61  *
  62  * <p> {@code Thread} defines constructors and a {@link Builder} to create threads.
  63  * {@linkplain #start() Starting} a thread schedules it to execute its {@link #run() run}
  64  * method. The newly started thread executes concurrently with the thread that caused

 273 
 274     // thread name
 275     private volatile String name;
 276 
 277     // interrupted status (read/written by VM)
 278     volatile boolean interrupted;
 279 
 280     // context ClassLoader
 281     private volatile ClassLoader contextClassLoader;
 282 
 283     // Additional fields for platform threads.
 284     // All fields, except task and terminatingThreadLocals, are accessed directly by the VM.
 285     private static class FieldHolder {
 286         final ThreadGroup group;
 287         final Runnable task;
 288         final long stackSize;
 289         volatile int priority;
 290         volatile boolean daemon;
 291         volatile int threadStatus;
 292 
 293         // Used by NativeThread for signalling, set lazily, read from any thread
 294         @Stable long nativeThreadID;
 295 
 296         // This map is maintained by the ThreadLocal class
 297         ThreadLocal.ThreadLocalMap terminatingThreadLocals;
 298 
 299         FieldHolder(ThreadGroup group,
 300                     Runnable task,
 301                     long stackSize,
 302                     int priority,
 303                     boolean daemon) {
 304             this.group = group;
 305             this.task = task;
 306             this.stackSize = stackSize;
 307             this.priority = priority;
 308             if (daemon)
 309                 this.daemon = true;
 310         }
 311     }
 312     private final FieldHolder holder;
 313 
 314     ThreadLocal.ThreadLocalMap terminatingThreadLocals() {
 315         return holder.terminatingThreadLocals;
 316     }
 317 
 318     void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) {
 319         holder.terminatingThreadLocals = map;
 320     }
 321 
 322     long nativeThreadID() {
 323         return holder.nativeThreadID;
 324     }
 325 
 326     void setNativeThreadID(long id) {
 327         holder.nativeThreadID = id;
 328     }
 329 
 330     /*
 331      * ThreadLocal values pertaining to this thread. This map is maintained
 332      * by the ThreadLocal class.
 333      */
 334     private ThreadLocal.ThreadLocalMap threadLocals;
 335 
 336     ThreadLocal.ThreadLocalMap threadLocals() {
 337         return threadLocals;
 338     }
 339 
 340     void setThreadLocals(ThreadLocal.ThreadLocalMap map) {
 341         threadLocals = map;
 342     }
 343 
 344     /*
 345      * InheritableThreadLocal values pertaining to this thread. This map is
 346      * maintained by the InheritableThreadLocal class.
 347      */
 348     private ThreadLocal.ThreadLocalMap inheritableThreadLocals;
 349 

 724         static {
 725             U = Unsafe.getUnsafe();
 726             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 727         }
 728         static long next() {
 729             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 730         }
 731     }
 732 
 733     /**
 734      * Initializes a platform Thread.
 735      *
 736      * @param g the Thread group, can be null
 737      * @param name the name of the new Thread
 738      * @param characteristics thread characteristics
 739      * @param task the object whose run() method gets called
 740      * @param stackSize the desired stack size for the new thread, or
 741      *        zero to indicate that this parameter is to be ignored.
 742      */
 743     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {

 744         Thread parent = currentThread();
 745         boolean attached = (parent == this);   // primordial or JNI attached
 746 
 747         if (attached) {
 748             if (g == null) {
 749                 throw new InternalError("group cannot be null when attaching");
 750             }
 751             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 752         } else {
 753             if (g == null) {
 754                 // default to current thread's group
 755                 g = parent.getThreadGroup();
 756             }
 757             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 758             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 759         }
 760 
 761         if (attached && VM.initLevel() < 1) {
 762             this.tid = PRIMORDIAL_TID;  // primordial thread
 763         } else {

 807             }
 808             this.contextClassLoader = parent.getContextClassLoader();
 809         } else {
 810             // default CCL to the system class loader when not inheriting
 811             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 812         }
 813 
 814         // special value to indicate this is a newly-created Thread
 815         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 816 
 817         // create a FieldHolder object, needed when bound to an OS thread
 818         if (bound) {
 819             ThreadGroup g = Constants.VTHREAD_GROUP;
 820             int pri = NORM_PRIORITY;
 821             this.holder = new FieldHolder(g, null, -1, pri, true);
 822         } else {
 823             this.holder = null;
 824         }
 825     }
 826 
 827     /**
 828      * The task that a {@linkplain VirtualThreadScheduler virtual thread scheduler}
 829      * executes on a platform thread to
 830      * {@linkplain VirtualThreadScheduler#onStart(VirtualThreadTask) start}
 831      * or {@linkplain VirtualThreadScheduler#onContinue(VirtualThreadTask) continue}
 832      * execution of a virtual thread. While executing the task, the platform thread is
 833      * the virtual thread's <em>carrier</em>.
 834      *
 835      * <p> There is a {@code VirtualThreadTask} object for each virtual thread. The
 836      * scheduler arranges to execute its {@link #run()} method when called to start or
 837      * continue the virtual thread, if possible on the {@linkplain #preferredCarrier()
 838      * preferred carrier thread}. The scheduler may attach an object to the task.
 839      *
 840      * @since 99
 841      */
 842     public sealed interface VirtualThreadTask extends Runnable permits
 843             VirtualThread.BuiltinSchedulerTask, VirtualThread.CustomSchedulerTask {
 844 
 845         /**
 846          * {@return the virtual thread that this task starts or continues}
 847          */
 848         Thread thread();
 849 
 850         /**
 851          * Runs the task on the current thread as the carrier thread.
 852          *
 853          * <p> Invoking this method with the interrupted status set will first
 854          * clear the interrupt status. Interrupting the carrier thread while
 855          * running the task leads to unspecified behavior.
 856          *
 857          * @throws IllegalStateException if the virtual thread is not in a state to
 858          * run on the current thread
 859          * @throws IllegalCallerException if the current thread is a virtual thread
 860          */
 861         @Override
 862         void run();
 863 
 864         /**
 865          * Returns the preferred carrier thread to execute this task. The scheduler may
 866          * choose to ignore this preference.
 867          * @return the preferred carrier thread or {@code null} if there is no preferred
 868          * carrier thread
 869          */
 870         Thread preferredCarrier();
 871 
 872         /**
 873          * Attaches the given object to this task.
 874          * @param att the object to attach
 875          * @return the previously-attached object, if any, otherwise {@code null}
 876          */
 877         Object attach(Object att);
 878 
 879         /**
 880          * Retrieves the current attachment.
 881          * @return the object currently attached to this task or {@code null} if
 882          * there is no attachment
 883          */
 884         Object attachment();
 885     }
 886 
 887     /**
 888      * Virtual thread scheduler.
 889      *
 890      * @apiNote The following example creates a virtual thread scheduler that uses a small
 891      * set of platform threads.
 892      * {@snippet lang=java :
 893      *     ExecutorService threadPool = Executors.newFixedThreadPool(4);
 894      *     var scheduler = new VirtualThreadScheduler() {
 895      *         private void submit(VirtualThreadTask task) {
 896      *             Thread caller = Thread.currentThread();
 897      *             threadPool.submit(() -> {
 898      *                 Thread vthread = task.thread();
 899      *                 Thread carrier = Thread.currentThread();
 900      *                 try {
 901      *                     task.run();
 902      *                 } finally {
 903      *                     assert Thread.currentThread() == carrier;
 904      *                     boolean terminated = !vthread.isAlive();
 905      *                 }
 906      *             });
 907      *         }
 908      *         @Override
 909      *         public void onStart(VirtualThreadTask task) {
 910      *             submit(task);
 911      *         }
 912      *         @Override
 913      *         public void onContinue(VirtualThreadTask task) {
 914      *             submit(task);
 915      *         }
 916      *    };
 917      * }
 918      *
 919      * <p> Unless otherwise specified, passing a null argument to a method in
 920      * this interface causes a {@code NullPointerException} to be thrown.
 921      *
 922      * @see Builder.OfVirtual#scheduler(VirtualThreadScheduler)
 923      * @since 99
 924      * @see VirtualThreadScheduler
 925      */
 926     public interface VirtualThreadScheduler {
 927         /**
 928          * Invoked by {@link Thread#start()} to start execution of a {@linkplain
 929          * VirtualThreadTask#thread() virtual thread}.
 930          * The scheduler's implementation of this method must arrange to execute the
 931          * given task's {@link VirtualThreadTask#run() run()} method on a platform thread.
 932          *
 933          * @implNote If invoked from a virtual thread, then the caller virtual thread is
 934          * <em>pinned</em> to its carrier while executing the {@code onStart} method.
 935          *
 936          * @param task the task to execute
 937          * @throws RejectedExecutionException if the scheduler cannot accept the task
 938          */
 939         void onStart(VirtualThreadTask task);
 940 
 941         /**
 942          * Invoked to continue execution of a {@linkplain VirtualThreadTask#thread()
 943          * virtual thread}.
 944          * The scheduler's implementation of this method must arrange to execute the
 945          * given task's {@link VirtualThreadTask#run() run()} method on a platform thread.
 946          *
 947          * @implNote If invoked from a virtual thread, then the caller virtual thread is
 948          * <em>pinned</em> to its carrier while executing the {@code onContinue} method.
 949          *
 950          * @param task the task to execute
 951          * @throws RejectedExecutionException if the scheduler cannot accept the task
 952          */
 953         void onContinue(VirtualThreadTask task);
 954 
 955         // -- prototype 2 --
 956 
 957         /**
 958          * {@return the virtual thread scheduler for the current virtual thread}
 959          * @throws UnsupportedOperationException if the current thread is not a virtual
 960          * thread or scheduling virtual threads to a user-provided scheduler is not
 961          * supported by this VM
 962          */
 963         @CallerSensitive
 964         @Restricted
 965         static VirtualThreadScheduler current() {
 966             Class<?> caller = Reflection.getCallerClass();
 967             caller.getModule().ensureNativeAccess(VirtualThreadScheduler.class,
 968                     "current",
 969                     caller,
 970                     false);
 971             if (Thread.currentThread() instanceof VirtualThread vthread) {
 972                 return vthread.scheduler(false);
 973             } else {
 974                 throw new UnsupportedOperationException();
 975             }
 976         }
 977     }
 978 
 979     /**
 980      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
 981      * that creates platform threads.
 982      *
 983      * @apiNote The following are examples using the builder:
 984      * {@snippet :
 985      *   // Start a daemon thread to run a task
 986      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
 987      *
 988      *   // Create an unstarted thread with name "duke", its start() method
 989      *   // must be invoked to schedule it to execute.
 990      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
 991      *
 992      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
 993      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
 994      * }
 995      *
 996      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
 997      * @since 21
 998      */

1213          * that creates virtual threads.
1214          *
1215          * <p> Unless otherwise specified, passing a null argument to a method in
1216          * this interface causes a {@code NullPointerException} to be thrown.
1217          *
1218          * @see Thread#ofVirtual()
1219          * @since 21
1220          */
1221         sealed interface OfVirtual extends Builder
1222                 permits ThreadBuilders.VirtualThreadBuilder {
1223 
1224             @Override OfVirtual name(String name);
1225 
1226             /**
1227              * @throws IllegalArgumentException {@inheritDoc}
1228              */
1229             @Override OfVirtual name(String prefix, long start);
1230 
1231             @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1232             @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
1233 
1234             // -- prototype 1 --
1235 
1236             /**
1237              * Creates a new virtual {@code Thread} from the current state of the builder
1238              * to run the given task. The {@code Thread}'s {@link Thread#start() start}
1239              * method must be invoked to schedule the thread to execute.
1240              * The {@code preferredCarrier} parameter is the preferred carrier thread to
1241              * execute the {@linkplain  VirtualThreadTask task} for the virtual thread.
1242              * The scheduler may choose to ignore this preference. The {@code att} is the
1243              * object to attach to the task.
1244              *
1245              * @param task the object to run when the thread executes
1246              * @param preferredCarrier the preferred carrier thread, can be {@code null}
1247              * @param att the object to attach, can be {@code null}
1248              * @return a new unstarted Thread
1249              * @since 99
1250              *
1251              * @see <a href="Thread.html#inheritance">Inheritance when creating threads</a>
1252              */
1253             @CallerSensitive
1254             @Restricted
1255             Thread unstarted(Runnable task, Thread preferredCarrier, Object att);
1256 
1257             // -- prototype 2 --
1258 
1259             /**
1260              * Sets the scheduler.
1261              *
1262              * <p> The virtual thread will be scheduled by the Java virtual machine with
1263              * the given scheduler. The scheduler's {@link
1264              * VirtualThreadScheduler#onStart(VirtualThreadTask) onStart} and
1265              * {@link VirtualThreadScheduler#onContinue(VirtualThreadTask) onContinue}
1266              * methods may be invoked in the context of a virtual thread. The scheduler
1267              * must arrange to execute the {@link VirtualThreadTask}'s
1268              * {@code run} method on a platform thread. Attempting to execute the run
1269              * method in a virtual thread causes {@link WrongThreadException} to be thrown.
1270              * The {@code onStart} and {@code onContinue }methods may be invoked at
1271              * sensitive times (e.g. when unparking a thread) so care should be taken to
1272              * not directly execute the task on the <em>current thread</em>.
1273              *
1274              * @param scheduler the scheduler
1275              * @return this builder
1276              * @throws UnsupportedOperationException if scheduling virtual threads to a
1277              *         user-provided scheduler is not supported by this VM
1278              * @since 99
1279              */
1280             @CallerSensitive
1281             @Restricted
1282             OfVirtual scheduler(VirtualThreadScheduler scheduler);
1283         }
1284     }
1285 
1286     /**
1287      * Throws CloneNotSupportedException as a Thread can not be meaningfully
1288      * cloned. Construct a new Thread instead.
1289      *
1290      * @throws  CloneNotSupportedException
1291      *          always
1292      */
1293     @Override
1294     protected Object clone() throws CloneNotSupportedException {
1295         throw new CloneNotSupportedException();
1296     }
1297 
1298     /**
1299      * Helper class for auto-numbering platform threads. The numbers start at
1300      * 0 and are separate from the thread identifier for historical reasons.
1301      */
1302     private static class ThreadNumbering {

1624     public Thread(ThreadGroup group, Runnable task, String name,
1625                   long stackSize, boolean inheritInheritableThreadLocals) {
1626         this(group, checkName(name),
1627                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1628                 task, stackSize);
1629     }
1630 
1631     /**
1632      * Creates a virtual thread to execute a task and schedules it to execute.
1633      *
1634      * <p> This method is equivalent to:
1635      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1636      *
1637      * @param task the object to run when the thread executes
1638      * @return a new, and started, virtual thread
1639      * @see <a href="#inheritance">Inheritance when creating threads</a>
1640      * @since 21
1641      */
1642     public static Thread startVirtualThread(Runnable task) {
1643         Objects.requireNonNull(task);
1644         var thread = ThreadBuilders.newVirtualThread(null, 0, task);
1645         thread.start();
1646         return thread;
1647     }
1648 
1649     /**
1650      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1651      * is scheduled by the Java virtual machine rather than the operating system.
1652      *
1653      * @return {@code true} if this thread is a virtual thread
1654      *
1655      * @since 21
1656      */
1657     public final boolean isVirtual() {
1658         return (this instanceof BaseVirtualThread);
1659     }
1660 
1661     /**
1662      * Schedules this thread to begin execution. The thread will execute
1663      * independently of the current thread.
1664      *
< prev index next >