< 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.foreign.ConfinedSegmentPool;
  38 import jdk.internal.event.ThreadSleepEvent;
  39 import jdk.internal.misc.TerminatingThreadLocal;
  40 import jdk.internal.misc.Unsafe;
  41 import jdk.internal.misc.VM;
  42 import jdk.internal.vm.Continuation;
  43 import jdk.internal.vm.ScopedValueContainer;
  44 import jdk.internal.vm.StackableScope;
  45 import jdk.internal.vm.ThreadContainer;
  46 import jdk.internal.vm.annotation.ForceInline;
  47 import jdk.internal.vm.annotation.Hidden;
  48 import jdk.internal.vm.annotation.IntrinsicCandidate;
  49 import jdk.internal.vm.annotation.Stable;
  50 import sun.nio.ch.Interruptible;
  51 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  52 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  53 
  54 /**
  55  * A <i>thread</i> is a thread of execution in a program. The Java

 745         static {
 746             U = Unsafe.getUnsafe();
 747             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 748         }
 749         static long next() {
 750             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 751         }
 752     }
 753 
 754     /**
 755      * Initializes a platform Thread.
 756      *
 757      * @param g the Thread group, can be null
 758      * @param name the name of the new Thread
 759      * @param characteristics thread characteristics
 760      * @param task the object whose run() method gets called
 761      * @param stackSize the desired stack size for the new thread, or
 762      *        zero to indicate that this parameter is to be ignored.
 763      */
 764     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
 765 
 766         Thread parent = currentThread();
 767         boolean attached = (parent == this);   // primordial or JNI attached
 768 
 769         if (attached) {
 770             if (g == null) {
 771                 throw new InternalError("group cannot be null when attaching");
 772             }
 773             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 774         } else {
 775             if (g == null) {
 776                 // default to current thread's group
 777                 g = parent.getThreadGroup();
 778             }
 779             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 780             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 781         }
 782 
 783         if (attached && VM.initLevel() < 1) {
 784             this.tid = PRIMORDIAL_TID;  // primordial thread
 785         } else {

 829             }
 830             this.contextClassLoader = parent.getContextClassLoader();
 831         } else {
 832             // default CCL to the system class loader when not inheriting
 833             this.contextClassLoader = ClassLoader.getSystemClassLoader();
 834         }
 835 
 836         // special value to indicate this is a newly-created Thread
 837         this.scopedValueBindings = NEW_THREAD_BINDINGS;
 838 
 839         // create a FieldHolder object, needed when bound to an OS thread
 840         if (bound) {
 841             ThreadGroup g = Constants.VTHREAD_GROUP;
 842             int pri = NORM_PRIORITY;
 843             this.holder = new FieldHolder(g, null, -1, pri, true);
 844         } else {
 845             this.holder = null;
 846         }
 847     }
 848 





























































































































































































 849     /**
 850      * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
 851      * that creates platform threads.
 852      *
 853      * @apiNote The following are examples using the builder:
 854      * {@snippet :
 855      *   // Start a daemon thread to run a task
 856      *   Thread thread = Thread.ofPlatform().daemon().start(runnable);
 857      *
 858      *   // Create an unstarted thread with name "duke", its start() method
 859      *   // must be invoked to schedule it to execute.
 860      *   Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
 861      *
 862      *   // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
 863      *   ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
 864      * }
 865      *
 866      * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
 867      * @since 21
 868      */

1444     public Thread(ThreadGroup group, Runnable task, String name,
1445                   long stackSize, boolean inheritInheritableThreadLocals) {
1446         this(group, checkName(name),
1447                 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1448                 task, stackSize);
1449     }
1450 
1451     /**
1452      * Creates a virtual thread to execute a task and schedules it to execute.
1453      *
1454      * <p> This method is equivalent to:
1455      * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1456      *
1457      * @param task the object to run when the thread executes
1458      * @return a new, and started, virtual thread
1459      * @see <a href="#inheritance">Inheritance when creating threads</a>
1460      * @since 21
1461      */
1462     public static Thread startVirtualThread(Runnable task) {
1463         Objects.requireNonNull(task);
1464         var thread = ThreadBuilders.newVirtualThread(null, null, 0, task);
1465         thread.start();
1466         return thread;
1467     }
1468 
1469     /**
1470      * Returns {@code true} if this thread is a virtual thread. A virtual thread
1471      * is scheduled by the Java virtual machine rather than the operating system.
1472      *
1473      * @return {@code true} if this thread is a virtual thread
1474      *
1475      * @since 21
1476      */
1477     public final boolean isVirtual() {
1478         return (this instanceof BaseVirtualThread);
1479     }
1480 
1481     /**
1482      * Schedules this thread to begin execution. The thread will execute
1483      * independently of the current thread.
1484      *

  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.foreign.ConfinedSegmentPool;
  41 import jdk.internal.event.ThreadSleepEvent;
  42 import jdk.internal.misc.TerminatingThreadLocal;
  43 import jdk.internal.misc.Unsafe;
  44 import jdk.internal.misc.VM;
  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

 748         static {
 749             U = Unsafe.getUnsafe();
 750             NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
 751         }
 752         static long next() {
 753             return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
 754         }
 755     }
 756 
 757     /**
 758      * Initializes a platform Thread.
 759      *
 760      * @param g the Thread group, can be null
 761      * @param name the name of the new Thread
 762      * @param characteristics thread characteristics
 763      * @param task the object whose run() method gets called
 764      * @param stackSize the desired stack size for the new thread, or
 765      *        zero to indicate that this parameter is to be ignored.
 766      */
 767     Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {

 768         Thread parent = currentThread();
 769         boolean attached = (parent == this);   // primordial or JNI attached
 770 
 771         if (attached) {
 772             if (g == null) {
 773                 throw new InternalError("group cannot be null when attaching");
 774             }
 775             this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
 776         } else {
 777             if (g == null) {
 778                 // default to current thread's group
 779                 g = parent.getThreadGroup();
 780             }
 781             int priority = Math.min(parent.getPriority(), g.getMaxPriority());
 782             this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
 783         }
 784 
 785         if (attached && VM.initLevel() < 1) {
 786             this.tid = PRIMORDIAL_TID;  // primordial thread
 787         } else {

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

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