< 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
  61  * it to start.
  62  *
  63  * <p> A thread <i>terminates</i> if either its {@code run} method completes normally,
  64  * or if its {@code run} method completes abruptly and the appropriate {@linkplain
  65  * Thread.UncaughtExceptionHandler uncaught exception handler} completes normally or
  66  * abruptly. With no code left to run, the thread has completed execution. The
  67  * {@link #join() join} method can be used to wait for a thread to terminate.
  68  *
  69  * <p> Threads have a unique {@linkplain #threadId() identifier} and a {@linkplain

 158  * status and thread priority from the parent thread at the time that the child {@code
 159  * Thread} is created. The {@linkplain ThreadGroup thread group} is also inherited when
 160  * not provided to the constructor. When using a {@code Thread.Builder} to create a
 161  * platform thread, the daemon status, thread priority, and thread group are inherited
 162  * when not set on the builder. As with the constructors, inheriting from the parent
 163  * thread is done when the child {@code Thread} is created.
 164  *
 165  * <p> A {@code Thread} inherits its initial values of {@linkplain InheritableThreadLocal
 166  * inheritable-thread-local} variables (including the context class loader) from
 167  * the parent thread values at the time that the child {@code Thread} is created.
 168  * The 5-param {@linkplain Thread#Thread(ThreadGroup, Runnable, String, long, boolean)
 169  * constructor} can be used to create a thread that does not inherit its initial
 170  * values from the constructing thread. When using a {@code Thread.Builder}, the
 171  * {@link Builder#inheritInheritableThreadLocals(boolean) inheritInheritableThreadLocals}
 172  * method can be used to select if the initial values are inherited.
 173  *
 174  * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
 175  * or method in this class will cause a {@link NullPointerException} to be thrown.
 176  *
 177  * @implNote
 178  * In the JDK Reference Implementation, the virtual thread scheduler may be configured
 179  * with the following system properties:
 180  * <table class="striped">
 181  * <caption style="display:none">System properties</caption>
 182  *   <thead>
 183  *   <tr>
 184  *     <th scope="col">System property</th>
 185  *     <th scope="col">Description</th>
 186  *   </tr>
 187  *   </thead>
 188  *   <tbody>
 189  *   <tr>
 190  *     <th scope="row">
 191  *       {@systemProperty jdk.virtualThreadScheduler.parallelism}
 192  *     </th>
 193  *     <td> The number of platform threads available for scheduling virtual
 194  *       threads. It defaults to the number of available processors. </td>
 195  *   </tr>
 196  *   <tr>
 197  *     <th scope="row">
 198  *       {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
 199  *     </th>
 200  *     <td> The maximum number of platform threads available to the scheduler.
 201  *       It defaults to 256. </td>
 202  *   </tr>
 203  *   </tbody>
 204  * </table>
 205  *
 206  * @since   1.0
 207  */
 208 public class Thread implements Runnable {
 209     /* Make sure registerNatives is the first thing <clinit> does. */
 210     private static native void registerNatives();
 211     static {
 212         registerNatives();
 213     }
 214 
 215     /*
 216      * Reserved for exclusive use by the JVM. Cannot be moved to the FieldHolder
 217      * as it needs to be set by the VM for JNI attaching threads, before executing
 218      * the constructor that will create the FieldHolder. The historically named
 219      * `eetop` holds the address of the underlying VM JavaThread, and is set to
 220      * non-zero when the thread is started, and reset to zero when the thread terminates.

 227 
 228     // thread name
 229     private volatile String name;
 230 
 231     // interrupt status (read/written by VM)
 232     volatile boolean interrupted;
 233 
 234     // context ClassLoader
 235     private volatile ClassLoader contextClassLoader;
 236 
 237     // Additional fields for platform threads.
 238     // All fields, except task and terminatingThreadLocals, are accessed directly by the VM.
 239     private static class FieldHolder {
 240         final ThreadGroup group;
 241         final Runnable task;
 242         final long stackSize;
 243         volatile int priority;
 244         volatile boolean daemon;
 245         volatile int threadStatus;
 246 



 247         // This map is maintained by the ThreadLocal class
 248         ThreadLocal.ThreadLocalMap terminatingThreadLocals;
 249 
 250         FieldHolder(ThreadGroup group,
 251                     Runnable task,
 252                     long stackSize,
 253                     int priority,
 254                     boolean daemon) {
 255             this.group = group;
 256             this.task = task;
 257             this.stackSize = stackSize;
 258             this.priority = priority;
 259             if (daemon)
 260                 this.daemon = true;
 261         }
 262     }
 263     private final FieldHolder holder;
 264 
 265     ThreadLocal.ThreadLocalMap terminatingThreadLocals() {
 266         return holder.terminatingThreadLocals;
 267     }
 268 
 269     void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) {
 270         holder.terminatingThreadLocals = map;
 271     }
 272 








 273     /*
 274      * ThreadLocal values pertaining to this thread. This map is maintained
 275      * by the ThreadLocal class.
 276      */
 277     private ThreadLocal.ThreadLocalMap threadLocals;
 278 
 279     ThreadLocal.ThreadLocalMap threadLocals() {
 280         return threadLocals;
 281     }
 282 
 283     void setThreadLocals(ThreadLocal.ThreadLocalMap map) {
 284         threadLocals = map;
 285     }
 286 
 287     /*
 288      * InheritableThreadLocal values pertaining to this thread. This map is
 289      * maintained by the InheritableThreadLocal class.
 290      */
 291     private ThreadLocal.ThreadLocalMap inheritableThreadLocals;
 292 

 667         static {
 668             U = Unsafe.getUnsafe();
 669             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 670         }
 671         static long next() {
 672             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 673         }
 674     }
 675 
 676     /**
 677      * Initializes a platform Thread.
 678      *
 679      * @param g the Thread group, can be null
 680      * @param name the name of the new Thread
 681      * @param characteristics thread characteristics
 682      * @param task the object whose run() method gets called
 683      * @param stackSize the desired stack size for the new thread, or
 684      *        zero to indicate that this parameter is to be ignored.
 685      */
 686     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
 687 
 688         Thread parent = currentThread();
 689         boolean attached = (parent == this);   // primordial or JNI attached
 690 
 691         if (attached) {
 692             if (g == null) {
 693                 throw new InternalError("group cannot be null when attaching");
 694             }
 695             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 696         } else {
 697             if (g == null) {
 698                 // default to current thread's group
 699                 g = parent.getThreadGroup();
 700             }
 701             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 702             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 703         }
 704 
 705         if (attached && VM.initLevel() < 1) {
 706             this.tid = PRIMORDIAL_TID;  // primordial thread
 707         } else {

 751             }
 752             this.contextClassLoader = parent.getContextClassLoader();
 753         } else {
 754             // default CCL to the system class loader when not inheriting
 755             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 756         }
 757 
 758         // special value to indicate this is a newly-created Thread
 759         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 760 
 761         // create a FieldHolder object, needed when bound to an OS thread
 762         if (bound) {
 763             ThreadGroup g = Constants.VTHREAD_GROUP;
 764             int pri = NORM_PRIORITY;
 765             this.holder = new FieldHolder(g, null, -1, pri, true);
 766         } else {
 767             this.holder = null;
 768         }
 769     }
 770 

















































































 771     /**
 772      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
 773      * that creates platform threads.
 774      *
 775      * @apiNote The following are examples using the builder:
 776      * {@snippet :
 777      *   // Start a daemon thread to run a task
 778      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
 779      *
 780      *   // Create an unstarted thread with name "duke", its start() method
 781      *   // must be invoked to schedule it to execute.
 782      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
 783      *
 784      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
 785      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
 786      * }
 787      *
 788      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
 789      * @since 21
 790      */

1005          * that creates virtual threads.
1006          *
1007          * <p> Unless otherwise specified, passing a null argument to a method in
1008          * this interface causes a {@code NullPointerException} to be thrown.
1009          *
1010          * @see Thread#ofVirtual()
1011          * @since 21
1012          */
1013         sealed interface OfVirtual extends Builder
1014                 permits ThreadBuilders.VirtualThreadBuilder {
1015 
1016             @Override OfVirtual name(String name);
1017 
1018             /**
1019              * @throws IllegalArgumentException {@inheritDoc}
1020              */
1021             @Override OfVirtual name(String prefix, long start);
1022 
1023             @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1024             @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);






















1025         }
1026     }
1027 
1028     /**
1029      * Throws CloneNotSupportedException as a Thread can not be meaningfully
1030      * cloned. Construct a new Thread instead.
1031      *
1032      * @throws  CloneNotSupportedException
1033      *          always
1034      */
1035     @Override
1036     protected Object clone() throws CloneNotSupportedException {
1037         throw new CloneNotSupportedException();
1038     }
1039 
1040     /**
1041      * Helper class for auto-numbering platform threads. The numbers start at
1042      * 0 and are separate from the thread identifier for historical reasons.
1043      */
1044     private static class ThreadNumbering {

1355      *         the desired stack size for the new thread, or zero to indicate
1356      *         that this parameter is to be ignored
1357      *
1358      * @param  inheritInheritableThreadLocals
1359      *         if {@code true}, inherit initial values for inheritable
1360      *         thread-locals from the constructing thread, otherwise no initial
1361      *         values are inherited
1362      *
1363      * @since 9
1364      * @see <a href="#inheritance">Inheritance when creating threads</a>
1365      */
1366     public Thread(ThreadGroup group, Runnable task, String name,
1367                   long stackSize, boolean inheritInheritableThreadLocals) {
1368         this(group, checkName(name),
1369                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1370                 task, stackSize);
1371     }
1372 
1373     /**
1374      * Creates a virtual thread to execute a task and schedules it to execute.

1375      *
1376      * <p> This method is equivalent to:
1377      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1378      *
1379      * @param task the object to run when the thread executes
1380      * @return a new, and started, virtual thread
1381      * @see <a href="#inheritance">Inheritance when creating threads</a>
1382      * @since 21
1383      */
1384     public static Thread startVirtualThread(Runnable task) {
1385         Objects.requireNonNull(task);
1386         var thread = ThreadBuilders.newVirtualThread(null, null, 0, task);
1387         thread.start();
1388         return thread;
1389     }
1390 
1391     /**
1392      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1393      * is scheduled by the Java virtual machine rather than the operating system.
1394      *

  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.Executor;
  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.vm.Continuation;
  45 import jdk.internal.vm.ScopedValueContainer;
  46 import jdk.internal.vm.StackableScope;
  47 import jdk.internal.vm.ThreadContainer;
  48 import jdk.internal.vm.annotation.ForceInline;
  49 import jdk.internal.vm.annotation.Hidden;
  50 import jdk.internal.vm.annotation.IntrinsicCandidate;
  51 import jdk.internal.vm.annotation.Stable;
  52 import sun.nio.ch.Interruptible;
  53 import sun.nio.ch.NativeThread;
  54 
  55 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  56 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  57 
  58 /**
  59  * A <i>thread</i> is a thread of execution in a program. The Java
  60  * virtual machine allows an application to have multiple threads of
  61  * execution running concurrently.
  62  *
  63  * <p> {@code Thread} defines constructors and a {@link Builder} to create threads.
  64  * {@linkplain #start() Starting} a thread schedules it to execute its {@link #run() run}
  65  * method. The newly started thread executes concurrently with the thread that caused
  66  * it to start.
  67  *
  68  * <p> A thread <i>terminates</i> if either its {@code run} method completes normally,
  69  * or if its {@code run} method completes abruptly and the appropriate {@linkplain
  70  * Thread.UncaughtExceptionHandler uncaught exception handler} completes normally or
  71  * abruptly. With no code left to run, the thread has completed execution. The
  72  * {@link #join() join} method can be used to wait for a thread to terminate.
  73  *
  74  * <p> Threads have a unique {@linkplain #threadId() identifier} and a {@linkplain

 163  * status and thread priority from the parent thread at the time that the child {@code
 164  * Thread} is created. The {@linkplain ThreadGroup thread group} is also inherited when
 165  * not provided to the constructor. When using a {@code Thread.Builder} to create a
 166  * platform thread, the daemon status, thread priority, and thread group are inherited
 167  * when not set on the builder. As with the constructors, inheriting from the parent
 168  * thread is done when the child {@code Thread} is created.
 169  *
 170  * <p> A {@code Thread} inherits its initial values of {@linkplain InheritableThreadLocal
 171  * inheritable-thread-local} variables (including the context class loader) from
 172  * the parent thread values at the time that the child {@code Thread} is created.
 173  * The 5-param {@linkplain Thread#Thread(ThreadGroup, Runnable, String, long, boolean)
 174  * constructor} can be used to create a thread that does not inherit its initial
 175  * values from the constructing thread. When using a {@code Thread.Builder}, the
 176  * {@link Builder#inheritInheritableThreadLocals(boolean) inheritInheritableThreadLocals}
 177  * method can be used to select if the initial values are inherited.
 178  *
 179  * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
 180  * or method in this class will cause a {@link NullPointerException} to be thrown.
 181  *
 182  * @implNote
 183  * In the JDK Reference Implementation, the following system properties may be used to
 184  * configure the default virtual thread scheduler:
 185  * <table class="striped">
 186  * <caption style="display:none">System properties</caption>
 187  *   <thead>
 188  *   <tr>
 189  *     <th scope="col">System property</th>
 190  *     <th scope="col">Description</th>
 191  *   </tr>
 192  *   </thead>
 193  *   <tbody>
 194  *   <tr>
 195  *     <th scope="row">
 196  *       {@systemProperty jdk.virtualThreadScheduler.parallelism}
 197  *     </th>
 198  *     <td> The default scheduler's target parallelism. It defaults to the number of
 199  *       available processors. </td>
 200  *   </tr>
 201  *   <tr>
 202  *     <th scope="row">
 203  *       {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
 204  *     </th>
 205  *     <td> The maximum number of platform threads available to the default scheduler.
 206  *       It defaults to 256. </td>
 207  *   </tr>
 208  *   </tbody>
 209  * </table>
 210  *
 211  * @since   1.0
 212  */
 213 public class Thread implements Runnable {
 214     /* Make sure registerNatives is the first thing <clinit> does. */
 215     private static native void registerNatives();
 216     static {
 217         registerNatives();
 218     }
 219 
 220     /*
 221      * Reserved for exclusive use by the JVM. Cannot be moved to the FieldHolder
 222      * as it needs to be set by the VM for JNI attaching threads, before executing
 223      * the constructor that will create the FieldHolder. The historically named
 224      * `eetop` holds the address of the underlying VM JavaThread, and is set to
 225      * non-zero when the thread is started, and reset to zero when the thread terminates.

 232 
 233     // thread name
 234     private volatile String name;
 235 
 236     // interrupt status (read/written by VM)
 237     volatile boolean interrupted;
 238 
 239     // context ClassLoader
 240     private volatile ClassLoader contextClassLoader;
 241 
 242     // Additional fields for platform threads.
 243     // All fields, except task and terminatingThreadLocals, are accessed directly by the VM.
 244     private static class FieldHolder {
 245         final ThreadGroup group;
 246         final Runnable task;
 247         final long stackSize;
 248         volatile int priority;
 249         volatile boolean daemon;
 250         volatile int threadStatus;
 251 
 252         // Native thread used for signalling, set lazily, read from any thread
 253         volatile NativeThread nativeThread;
 254 
 255         // This map is maintained by the ThreadLocal class
 256         ThreadLocal.ThreadLocalMap terminatingThreadLocals;
 257 
 258         FieldHolder(ThreadGroup group,
 259                     Runnable task,
 260                     long stackSize,
 261                     int priority,
 262                     boolean daemon) {
 263             this.group = group;
 264             this.task = task;
 265             this.stackSize = stackSize;
 266             this.priority = priority;
 267             if (daemon)
 268                 this.daemon = true;
 269         }
 270     }
 271     private final FieldHolder holder;
 272 
 273     ThreadLocal.ThreadLocalMap terminatingThreadLocals() {
 274         return holder.terminatingThreadLocals;
 275     }
 276 
 277     void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) {
 278         holder.terminatingThreadLocals = map;
 279     }
 280 
 281     NativeThread nativeThread() {
 282         return holder.nativeThread;
 283     }
 284 
 285     void setNativeThread(NativeThread nt) {
 286         holder.nativeThread = nt;
 287     }
 288 
 289     /*
 290      * ThreadLocal values pertaining to this thread. This map is maintained
 291      * by the ThreadLocal class.
 292      */
 293     private ThreadLocal.ThreadLocalMap threadLocals;
 294 
 295     ThreadLocal.ThreadLocalMap threadLocals() {
 296         return threadLocals;
 297     }
 298 
 299     void setThreadLocals(ThreadLocal.ThreadLocalMap map) {
 300         threadLocals = map;
 301     }
 302 
 303     /*
 304      * InheritableThreadLocal values pertaining to this thread. This map is
 305      * maintained by the InheritableThreadLocal class.
 306      */
 307     private ThreadLocal.ThreadLocalMap inheritableThreadLocals;
 308 

 683         static {
 684             U = Unsafe.getUnsafe();
 685             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 686         }
 687         static long next() {
 688             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 689         }
 690     }
 691 
 692     /**
 693      * Initializes a platform Thread.
 694      *
 695      * @param g the Thread group, can be null
 696      * @param name the name of the new Thread
 697      * @param characteristics thread characteristics
 698      * @param task the object whose run() method gets called
 699      * @param stackSize the desired stack size for the new thread, or
 700      *        zero to indicate that this parameter is to be ignored.
 701      */
 702     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {

 703         Thread parent = currentThread();
 704         boolean attached = (parent == this);   // primordial or JNI attached
 705 
 706         if (attached) {
 707             if (g == null) {
 708                 throw new InternalError("group cannot be null when attaching");
 709             }
 710             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 711         } else {
 712             if (g == null) {
 713                 // default to current thread's group
 714                 g = parent.getThreadGroup();
 715             }
 716             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 717             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 718         }
 719 
 720         if (attached && VM.initLevel() < 1) {
 721             this.tid = PRIMORDIAL_TID;  // primordial thread
 722         } else {

 766             }
 767             this.contextClassLoader = parent.getContextClassLoader();
 768         } else {
 769             // default CCL to the system class loader when not inheriting
 770             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 771         }
 772 
 773         // special value to indicate this is a newly-created Thread
 774         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 775 
 776         // create a FieldHolder object, needed when bound to an OS thread
 777         if (bound) {
 778             ThreadGroup g = Constants.VTHREAD_GROUP;
 779             int pri = NORM_PRIORITY;
 780             this.holder = new FieldHolder(g, null, -1, pri, true);
 781         } else {
 782             this.holder = null;
 783         }
 784     }
 785 
 786     /**
 787      * The task {@link java.util.concurrent.Executor#execute(Runnable) submitted} to
 788      * a user-provided {@link Thread.Builder.OfVirtual#scheduler(Executor) scheduler}.
 789      *
 790      * @apiNote The following example creates a scheduler that uses a small set of
 791      * platform threads.
 792      * <pre>{@code
 793      *     ExecutorService pool = Executors.newFixedThreadPool(4);
 794      *     Executor scheduler = (task) -> {
 795      *         // invoke pool.execute in the context of the caller
 796      *         pool.execute(() -> {
 797      *             Thread carrier = Thread.currentThread();
 798      *             Thread vthread = ((Thread.VirtualThreadTask) task).thread();
 799      *
 800      *             // runs virtual thread task
 801      *             task.run();
 802      *
 803      *             assert Thread.currentThread() == carrier;
 804      *         }));
 805      *     };
 806      * }</pre>
 807      *
 808      * @see Thread.Builder.OfVirtual#scheduler(Executor)
 809      * @since 99
 810      */
 811     public interface VirtualThreadTask extends Runnable {
 812 
 813         /**
 814          * Return the virtual thread that this task was submitted to run
 815          * @return the virtual thread
 816          */
 817         Thread thread();
 818 
 819         /**
 820          * Attaches the given object to this task.
 821          * @param att the object to attach
 822          * @return the previously-attached object, if any, otherwise {@code null}
 823          */
 824         Object attach(Object att);
 825 
 826         /**
 827          * Retrieves the current attachment.
 828          * @return the object currently attached to this task or {@code null} if
 829          *         there is no attachment
 830          */
 831         Object attachment();
 832 
 833         /**
 834          * Returns the object currently attached to the {@code VirtualThreadTask} for
 835          * the current virtual thread.
 836          * @return the object currently attached to current virtual thread's task
 837          * @throws IllegalCallerException if the current thread is a platform thread
 838          */
 839         static Object currentVirtualThreadTaskAttachment() {
 840             Thread t = Thread.currentThread();
 841             if (t instanceof VirtualThread vthread) {
 842                 return vthread.currentTaskAttachment();
 843             } else if (t.isVirtual()) {
 844                 // not supported with BoundVirtualThread
 845                 return null;
 846             } else {
 847                 // platform thread
 848                 throw new IllegalCallerException();
 849             }
 850         }
 851 
 852         /**
 853          * Runs the task on the current thread as the carrier thread.
 854          *
 855          * <p> Invoking this method with the interrupt status set will first
 856          * clear the interrupt status. Interrupting the carrier thread while
 857          * running the task leads to unspecified behavior.
 858          *
 859          * @throws IllegalStateException if the virtual thread is not in a state to
 860          *         run on the current thread
 861          * @throws IllegalCallerException if the current thread is a virtual thread
 862          */
 863         @Override
 864         void run();
 865     }
 866 
 867     /**
 868      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
 869      * that creates platform threads.
 870      *
 871      * @apiNote The following are examples using the builder:
 872      * {@snippet :
 873      *   // Start a daemon thread to run a task
 874      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
 875      *
 876      *   // Create an unstarted thread with name "duke", its start() method
 877      *   // must be invoked to schedule it to execute.
 878      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
 879      *
 880      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
 881      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
 882      * }
 883      *
 884      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
 885      * @since 21
 886      */

1101          * that creates virtual threads.
1102          *
1103          * <p> Unless otherwise specified, passing a null argument to a method in
1104          * this interface causes a {@code NullPointerException} to be thrown.
1105          *
1106          * @see Thread#ofVirtual()
1107          * @since 21
1108          */
1109         sealed interface OfVirtual extends Builder
1110                 permits ThreadBuilders.VirtualThreadBuilder {
1111 
1112             @Override OfVirtual name(String name);
1113 
1114             /**
1115              * @throws IllegalArgumentException {@inheritDoc}
1116              */
1117             @Override OfVirtual name(String prefix, long start);
1118 
1119             @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1120             @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
1121 
1122             /**
1123              * Sets the scheduler.
1124              * The thread will be scheduled by the Java virtual machine with the given
1125              * scheduler. The scheduler's {@link Executor#execute(Runnable) execute}
1126              * method is invoked with tasks of type {@link Thread.VirtualThreadTask}. It
1127              * may be invoked in the context of a virtual thread. The scheduler should
1128              * arrange to execute these tasks on a platform thread. Attempting to execute
1129              * the task on a virtual thread causes an exception to be thrown (see
1130              * {@link Thread.VirtualThreadTask#run() VirtualThreadTask.run}). The {@code
1131              * execute} method may be invoked at sensitive times (e.g. when unparking a
1132              * thread) so care should be taken to not directly execute the task on the
1133              * <em>current thread</em>.
1134              *
1135              * @param scheduler the scheduler
1136              * @return this builder
1137              * @throws UnsupportedOperationException if scheduling virtual threads to a
1138              *         user-provided scheduler is not supported by this VM
1139              */
1140             @CallerSensitive
1141             @Restricted
1142             OfVirtual scheduler(Executor scheduler);
1143         }
1144     }
1145 
1146     /**
1147      * Throws CloneNotSupportedException as a Thread can not be meaningfully
1148      * cloned. Construct a new Thread instead.
1149      *
1150      * @throws  CloneNotSupportedException
1151      *          always
1152      */
1153     @Override
1154     protected Object clone() throws CloneNotSupportedException {
1155         throw new CloneNotSupportedException();
1156     }
1157 
1158     /**
1159      * Helper class for auto-numbering platform threads. The numbers start at
1160      * 0 and are separate from the thread identifier for historical reasons.
1161      */
1162     private static class ThreadNumbering {

1473      *         the desired stack size for the new thread, or zero to indicate
1474      *         that this parameter is to be ignored
1475      *
1476      * @param  inheritInheritableThreadLocals
1477      *         if {@code true}, inherit initial values for inheritable
1478      *         thread-locals from the constructing thread, otherwise no initial
1479      *         values are inherited
1480      *
1481      * @since 9
1482      * @see <a href="#inheritance">Inheritance when creating threads</a>
1483      */
1484     public Thread(ThreadGroup group, Runnable task, String name,
1485                   long stackSize, boolean inheritInheritableThreadLocals) {
1486         this(group, checkName(name),
1487                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1488                 task, stackSize);
1489     }
1490 
1491     /**
1492      * Creates a virtual thread to execute a task and schedules it to execute.
1493      * The thread is scheduled to the default virtual thread scheduler.
1494      *
1495      * <p> This method is equivalent to:
1496      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1497      *
1498      * @param task the object to run when the thread executes
1499      * @return a new, and started, virtual thread
1500      * @see <a href="#inheritance">Inheritance when creating threads</a>
1501      * @since 21
1502      */
1503     public static Thread startVirtualThread(Runnable task) {
1504         Objects.requireNonNull(task);
1505         var thread = ThreadBuilders.newVirtualThread(null, null, 0, task);
1506         thread.start();
1507         return thread;
1508     }
1509 
1510     /**
1511      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1512      * is scheduled by the Java virtual machine rather than the operating system.
1513      *
< prev index next >