< 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      *

2191      * scheduled to run by the system, or has terminated.
2192      * If the returned array is of non-zero length then the first element of
2193      * the array represents the top of the stack, which is the most recent
2194      * method invocation in the sequence.  The last element of the array
2195      * represents the bottom of the stack, which is the least recent method
2196      * invocation in the sequence.
2197      *
2198      * <p>Some virtual machines may, under some circumstances, omit one
2199      * or more stack frames from the stack trace.  In the extreme case,
2200      * a virtual machine that has no stack trace information concerning
2201      * this thread is permitted to return a zero-length array from this
2202      * method.
2203      *
2204      * @return an array of {@code StackTraceElement},
2205      * each represents one stack frame.
2206      *
2207      * @see Throwable#getStackTrace
2208      * @since 1.5
2209      */
2210     public StackTraceElement[] getStackTrace() {
2211         if (this != Thread.currentThread()) {
2212             // optimization so we do not call into the vm for threads that
2213             // have not yet started or have terminated
2214             if (!isAlive()) {
2215                 return EMPTY_STACK_TRACE;
2216             }
2217             StackTraceElement[] stackTrace = asyncGetStackTrace();
2218             return (stackTrace != null) ? stackTrace : EMPTY_STACK_TRACE;



2219         } else {
2220             return (new Exception()).getStackTrace();
2221         }
2222     }
2223 
2224     /**
2225      * Returns an array of stack trace elements representing the stack dump of
2226      * this thread. Returns null if the stack trace cannot be obtained. In
2227      * the default implementation, null is returned if the thread is a virtual
2228      * thread that is not mounted or the thread is a platform thread that has
2229      * terminated.
2230      */
2231     StackTraceElement[] asyncGetStackTrace() {
2232         Object stackTrace = getStackTrace0();
2233         if (stackTrace == null) {
2234             return null;
2235         }
2236         StackTraceElement[] stes = (StackTraceElement[]) stackTrace;
2237         if (stes.length == 0) {
2238             return null;
2239         } else {
2240             return StackTraceElement.of(stes);
2241         }
2242     }
2243 
2244     private native Object getStackTrace0();
2245 
2246     /**
2247      * Returns a map of stack traces for all live platform threads. The map
2248      * does not include virtual threads.
2249      * The map keys are threads and each map value is an array of
2250      * {@code StackTraceElement} that represents the stack dump
2251      * of the corresponding {@code Thread}.
2252      * The returned stack traces are in the format specified for
2253      * the {@link #getStackTrace getStackTrace} method.
2254      *
2255      * <p>The threads may be executing while this method is called.
2256      * The stack trace of each thread only represents a snapshot and
2257      * each stack trace may be obtained at different time.  A zero-length
2258      * array will be returned in the map value if the virtual machine has
2259      * no stack trace information about a thread.
2260      *
2261      * @return a {@code Map} from {@code Thread} to an array of
2262      * {@code StackTraceElement} that represents the stack trace of
2263      * the corresponding thread.

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

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

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

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

 809             }
 810             this.contextClassLoader = parent.getContextClassLoader();
 811         } else {
 812             // default CCL to the system class loader when not inheriting
 813             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 814         }
 815 
 816         // special value to indicate this is a newly-created Thread
 817         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 818 
 819         // create a FieldHolder object, needed when bound to an OS thread
 820         if (bound) {
 821             ThreadGroup g = Constants.VTHREAD_GROUP;
 822             int pri = NORM_PRIORITY;
 823             this.holder = new FieldHolder(g, null, -1, pri, true);
 824         } else {
 825             this.holder = null;
 826         }
 827     }
 828 
 829     /**
 830      * The task that a {@linkplain VirtualThreadScheduler virtual thread scheduler}
 831      * executes on a platform thread to
 832      * {@linkplain VirtualThreadScheduler#onStart(VirtualThreadTask) start}
 833      * or {@linkplain VirtualThreadScheduler#onContinue(VirtualThreadTask) continue}
 834      * execution of a virtual thread. While executing the task, the platform thread is
 835      * the virtual thread's <em>carrier</em>.
 836      *
 837      * <p> There is a {@code VirtualThreadTask} object for each virtual thread. The
 838      * scheduler arranges to execute its {@link #run()} method when called to start or
 839      * continue the virtual thread, if possible on the {@linkplain #preferredCarrier()
 840      * preferred carrier thread}. The scheduler may attach an object to the task.
 841      *
 842      * @since 99
 843      */
 844     public sealed interface VirtualThreadTask extends Runnable permits
 845             VirtualThread.BuiltinSchedulerTask, VirtualThread.CustomSchedulerTask {
 846 
 847         /**
 848          * {@return the virtual thread that this task starts or continues}
 849          */
 850         Thread thread();
 851 
 852         /**
 853          * Runs the task on the current thread as the carrier thread.
 854          *
 855          * <p> Invoking this method with the interrupted 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          * Returns the preferred carrier thread to execute this task. The scheduler may
 868          * choose to ignore this preference.
 869          * @return the preferred carrier thread or {@code null} if there is no preferred
 870          * carrier thread
 871          */
 872         Thread preferredCarrier();
 873 
 874         /**
 875          * Attaches the given object to this task.
 876          * @param att the object to attach
 877          * @return the previously-attached object, if any, otherwise {@code null}
 878          */
 879         Object attach(Object att);
 880 
 881         /**
 882          * Retrieves the current attachment.
 883          * @return the object currently attached to this task or {@code null} if
 884          * there is no attachment
 885          */
 886         Object attachment();
 887     }
 888 
 889     /**
 890      * Virtual thread scheduler.
 891      *
 892      * @apiNote The following example creates a virtual thread scheduler that uses a small
 893      * set of platform threads.
 894      * {@snippet lang=java :
 895      *     ExecutorService threadPool = Executors.newFixedThreadPool(4);
 896      *     var scheduler = new VirtualThreadScheduler() {
 897      *         private void submit(VirtualThreadTask task) {
 898      *             Thread caller = Thread.currentThread();
 899      *             threadPool.submit(() -> {
 900      *                 Thread vthread = task.thread();
 901      *                 Thread carrier = Thread.currentThread();
 902      *                 try {
 903      *                     task.run();
 904      *                 } finally {
 905      *                     assert Thread.currentThread() == carrier;
 906      *                     boolean terminated = !vthread.isAlive();
 907      *                 }
 908      *             });
 909      *         }
 910      *         @Override
 911      *         public void onStart(VirtualThreadTask task) {
 912      *             submit(task);
 913      *         }
 914      *         @Override
 915      *         public void onContinue(VirtualThreadTask task) {
 916      *             submit(task);
 917      *         }
 918      *    };
 919      * }
 920      *
 921      * <p> Unless otherwise specified, passing a null argument to a method in
 922      * this interface causes a {@code NullPointerException} to be thrown.
 923      *
 924      * @since 99
 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 1 --
 956 
 957         /**
 958          * Creates a new virtual thread, returning the {@code VirtualThreadTask} that the
 959          * virtual thread scheduler arranges to execute on a platform thread to start or
 960          * continue execution of the virtual thread.
 961          *
 962          * <p> This method creates a new unstarted {@code Thread} from the current state
 963          * of the given builder to run the given task. The {@link VirtualThreadTask#thread()
 964          * thread()} method returns the virtual threa. The thread's {@link Thread#start()
 965          * start()} method must be invoked to schedule the thread to begin execution.
 966          *
 967          * @apiNote This method is intended for frameworks that make use of a custom
 968          * {@link VirtualThreadScheduler VirtualThreadScheduler} and wish to specify a
 969          * preferred carrier thread when creating a virtual thread, or need a reference
 970          * to the virtual thread task before the virtual thread is started. The
 971          * framework can use the {@link VirtualThreadTask#attach(Object) attach(Object)}
 972          * method to attach its context object to the task before the thread is started.
 973          *
 974          * @implSpec The default implementation creates a new virtual thread. It should
 975          * be rare to override this method.
 976          *
 977          * @param builder the virtual thread builder
 978          * @param preferredCarrier the preferred carrirer, can be {@code null}
 979          * @param task the object to run when the thread executes
 980          * @return the {@code VirtualThreadTask} that scheduler executes
 981          * @throws UnsupportedOperationException if this is the built-in default scheduler
 982          *
 983          * @see <a href="Thread.html#inheritance">Inheritance when creating threads</a>
 984          */
 985         default VirtualThreadTask newThread(Builder.OfVirtual builder,
 986                                             Thread preferredCarrier,
 987                                             Runnable task) {
 988             Objects.requireNonNull(builder);
 989             Objects.requireNonNull(task);
 990             if (this == VirtualThread.builtinScheduler(false)) {
 991                 throw new UnsupportedOperationException();
 992             }
 993             var vbuilder = (ThreadBuilders.VirtualThreadBuilder) builder;
 994             var vthread = (VirtualThread) vbuilder.unstarted(task, preferredCarrier);
 995             return vthread.virtualThreadTask();
 996         }
 997 
 998         /**
 999          * Schedules a task that becomes enabled for execution after the given delay.
1000          *
1001          * <p> This method is invoked to schedule delayed tasks in support of timed
1002          * operations and methods such as {@link Thread#sleep(long)} and {@link
1003          * Object#wait(long)}. The scheduler should arrange to execute the task on
1004          * a platform thread.
1005          *
1006          * @implSpec The default implementation schedules the task to execute after
1007          * the given delay. The task executes on JDK internal thread. An implementation
1008          * may wish to override this method when it is capable of scheduling delayed
1009          * tasks.
1010          *
1011          * @param task the task to execute
1012          * @param delay the time from now to delay execution
1013          * @param unit the time unit of the delay parameter
1014          * @return a Future representing pending completion of the task
1015          */
1016         default Future<?> schedule(Runnable task, long delay, TimeUnit unit) {
1017             return VirtualThread.DelayedTaskSchedulers.schedule(task, delay, unit);
1018         }
1019 
1020         // -- prototype 2 --
1021 
1022         /**
1023          * {@return the virtual thread scheduler for the current virtual thread}
1024          * @throws UnsupportedOperationException if the current thread is not a virtual
1025          * thread or scheduling virtual threads to a user-provided scheduler is not
1026          * supported by this VM
1027          */
1028         @Deprecated(forRemoval=true)
1029         @CallerSensitive
1030         @Restricted
1031         static VirtualThreadScheduler current() {
1032             if (Thread.currentThread() instanceof VirtualThread vthread) {
1033                 Class<?> caller = Reflection.getCallerClass();
1034                 caller.getModule().ensureNativeAccess(VirtualThreadScheduler.class,
1035                                                      "current",
1036                                                       caller,
1037                                                       false);
1038                 return vthread.scheduler(false);
1039             }
1040             throw new UnsupportedOperationException();
1041         }
1042     }
1043 
1044     /**
1045      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
1046      * that creates platform threads.
1047      *
1048      * @apiNote The following are examples using the builder:
1049      * {@snippet :
1050      *   // Start a daemon thread to run a task
1051      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
1052      *
1053      *   // Create an unstarted thread with name "duke", its start() method
1054      *   // must be invoked to schedule it to execute.
1055      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
1056      *
1057      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
1058      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
1059      * }
1060      *
1061      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
1062      * @since 21
1063      */

1278          * that creates virtual threads.
1279          *
1280          * <p> Unless otherwise specified, passing a null argument to a method in
1281          * this interface causes a {@code NullPointerException} to be thrown.
1282          *
1283          * @see Thread#ofVirtual()
1284          * @since 21
1285          */
1286         sealed interface OfVirtual extends Builder
1287                 permits ThreadBuilders.VirtualThreadBuilder {
1288 
1289             @Override OfVirtual name(String name);
1290 
1291             /**
1292              * @throws IllegalArgumentException {@inheritDoc}
1293              */
1294             @Override OfVirtual name(String prefix, long start);
1295 
1296             @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1297             @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
1298 
1299             // -- prototype 2 --
1300 
1301             /**
1302              * Sets the scheduler.
1303              *
1304              * <p> The virtual thread will be scheduled by the Java virtual machine with
1305              * the given scheduler. The scheduler's {@link
1306              * VirtualThreadScheduler#onStart(VirtualThreadTask) onStart} and
1307              * {@link VirtualThreadScheduler#onContinue(VirtualThreadTask) onContinue}
1308              * methods may be invoked in the context of a virtual thread. The scheduler
1309              * must arrange to execute the {@link VirtualThreadTask}'s
1310              * {@code run} method on a platform thread. Attempting to execute the run
1311              * method in a virtual thread causes {@link WrongThreadException} to be thrown.
1312              * The {@code onStart} and {@code onContinue }methods may be invoked at
1313              * sensitive times (e.g. when unparking a thread) so care should be taken to
1314              * not directly execute the task on the <em>current thread</em>.
1315              *
1316              * @param scheduler the scheduler
1317              * @return this builder
1318              * @throws UnsupportedOperationException if scheduling virtual threads to a
1319              *         user-provided scheduler is not supported by this VM
1320              * @since 99
1321              */
1322             @Deprecated(forRemoval=true)
1323             @CallerSensitive
1324             @Restricted
1325             OfVirtual scheduler(VirtualThreadScheduler scheduler);
1326         }
1327     }
1328 
1329     /**
1330      * Throws CloneNotSupportedException as a Thread can not be meaningfully
1331      * cloned. Construct a new Thread instead.
1332      *
1333      * @throws  CloneNotSupportedException
1334      *          always
1335      */
1336     @Override
1337     protected Object clone() throws CloneNotSupportedException {
1338         throw new CloneNotSupportedException();
1339     }
1340 
1341     /**
1342      * Helper class for auto-numbering platform threads. The numbers start at
1343      * 0 and are separate from the thread identifier for historical reasons.
1344      */
1345     private static class ThreadNumbering {

1667     public Thread(ThreadGroup group, Runnable task, String name,
1668                   long stackSize, boolean inheritInheritableThreadLocals) {
1669         this(group, checkName(name),
1670                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1671                 task, stackSize);
1672     }
1673 
1674     /**
1675      * Creates a virtual thread to execute a task and schedules it to execute.
1676      *
1677      * <p> This method is equivalent to:
1678      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1679      *
1680      * @param task the object to run when the thread executes
1681      * @return a new, and started, virtual thread
1682      * @see <a href="#inheritance">Inheritance when creating threads</a>
1683      * @since 21
1684      */
1685     public static Thread startVirtualThread(Runnable task) {
1686         Objects.requireNonNull(task);
1687         var thread = ThreadBuilders.newVirtualThread(null, 0, task);
1688         thread.start();
1689         return thread;
1690     }
1691 
1692     /**
1693      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1694      * is scheduled by the Java virtual machine rather than the operating system.
1695      *
1696      * @return {@code true} if this thread is a virtual thread
1697      *
1698      * @since 21
1699      */
1700     public final boolean isVirtual() {
1701         return (this instanceof BaseVirtualThread);
1702     }
1703 
1704     /**
1705      * Schedules this thread to begin execution. The thread will execute
1706      * independently of the current thread.
1707      *

2450      * scheduled to run by the system, or has terminated.
2451      * If the returned array is of non-zero length then the first element of
2452      * the array represents the top of the stack, which is the most recent
2453      * method invocation in the sequence.  The last element of the array
2454      * represents the bottom of the stack, which is the least recent method
2455      * invocation in the sequence.
2456      *
2457      * <p>Some virtual machines may, under some circumstances, omit one
2458      * or more stack frames from the stack trace.  In the extreme case,
2459      * a virtual machine that has no stack trace information concerning
2460      * this thread is permitted to return a zero-length array from this
2461      * method.
2462      *
2463      * @return an array of {@code StackTraceElement},
2464      * each represents one stack frame.
2465      *
2466      * @see Throwable#getStackTrace
2467      * @since 1.5
2468      */
2469     public StackTraceElement[] getStackTrace() {
2470         if (Thread.currentThread() != this) {
2471             // optimization so we do not call into the vm for threads that
2472             // have not yet started or have terminated
2473             if (!isAlive()) {
2474                 return EMPTY_STACK_TRACE;
2475             }
2476             Object trace = getStackTrace0();
2477             if (trace instanceof StackTraceElement[] stackTrace) {
2478                 return StackTraceElement.finishInit(stackTrace);
2479             }
2480             return EMPTY_STACK_TRACE;
2481         } else {
2482             return (new Exception()).getStackTrace();
2483         }
2484     }
2485 




















2486     private native Object getStackTrace0();
2487 
2488     /**
2489      * Returns a map of stack traces for all live platform threads. The map
2490      * does not include virtual threads.
2491      * The map keys are threads and each map value is an array of
2492      * {@code StackTraceElement} that represents the stack dump
2493      * of the corresponding {@code Thread}.
2494      * The returned stack traces are in the format specified for
2495      * the {@link #getStackTrace getStackTrace} method.
2496      *
2497      * <p>The threads may be executing while this method is called.
2498      * The stack trace of each thread only represents a snapshot and
2499      * each stack trace may be obtained at different time.  A zero-length
2500      * array will be returned in the map value if the virtual machine has
2501      * no stack trace information about a thread.
2502      *
2503      * @return a {@code Map} from {@code Thread} to an array of
2504      * {@code StackTraceElement} that represents the stack trace of
2505      * the corresponding thread.
< prev index next >