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
720 static {
721 U = Unsafe.getUnsafe();
722 NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
723 }
724 static long next() {
725 return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
726 }
727 }
728
729 /**
730 * Initializes a platform Thread.
731 *
732 * @param g the Thread group, can be null
733 * @param name the name of the new Thread
734 * @param characteristics thread characteristics
735 * @param task the object whose run() method gets called
736 * @param stackSize the desired stack size for the new thread, or
737 * zero to indicate that this parameter is to be ignored.
738 */
739 Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
740
741 Thread parent = currentThread();
742 boolean attached = (parent == this); // primordial or JNI attached
743
744 if (attached) {
745 if (g == null) {
746 throw new InternalError("group cannot be null when attaching");
747 }
748 this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
749 } else {
750 if (g == null) {
751 // default to current thread's group
752 g = parent.getThreadGroup();
753 }
754 int priority = Math.min(parent.getPriority(), g.getMaxPriority());
755 this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
756 }
757
758 if (attached && VM.initLevel() < 1) {
759 this.tid = PRIMORDIAL_TID; // primordial thread
760 } else {
804 }
805 this.contextClassLoader = parent.getContextClassLoader();
806 } else {
807 // default CCL to the system class loader when not inheriting
808 this.contextClassLoader = ClassLoader.getSystemClassLoader();
809 }
810
811 // special value to indicate this is a newly-created Thread
812 this.scopedValueBindings = NEW_THREAD_BINDINGS;
813
814 // create a FieldHolder object, needed when bound to an OS thread
815 if (bound) {
816 ThreadGroup g = Constants.VTHREAD_GROUP;
817 int pri = NORM_PRIORITY;
818 this.holder = new FieldHolder(g, null, -1, pri, true);
819 } else {
820 this.holder = null;
821 }
822 }
823
824 /**
825 * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
826 * that creates platform threads.
827 *
828 * @apiNote The following are examples using the builder:
829 * {@snippet :
830 * // Start a daemon thread to run a task
831 * Thread thread = Thread.ofPlatform().daemon().start(runnable);
832 *
833 * // Create an unstarted thread with name "duke", its start() method
834 * // must be invoked to schedule it to execute.
835 * Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
836 *
837 * // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
838 * ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
839 * }
840 *
841 * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
842 * @since 21
843 */
1058 * that creates virtual threads.
1059 *
1060 * <p> Unless otherwise specified, passing a null argument to a method in
1061 * this interface causes a {@code NullPointerException} to be thrown.
1062 *
1063 * @see Thread#ofVirtual()
1064 * @since 21
1065 */
1066 sealed interface OfVirtual extends Builder
1067 permits ThreadBuilders.VirtualThreadBuilder {
1068
1069 @Override OfVirtual name(String name);
1070
1071 /**
1072 * @throws IllegalArgumentException {@inheritDoc}
1073 */
1074 @Override OfVirtual name(String prefix, long start);
1075
1076 @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1077 @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
1078 }
1079 }
1080
1081 /**
1082 * Throws CloneNotSupportedException as a Thread can not be meaningfully
1083 * cloned. Construct a new Thread instead.
1084 *
1085 * @throws CloneNotSupportedException
1086 * always
1087 */
1088 @Override
1089 protected Object clone() throws CloneNotSupportedException {
1090 throw new CloneNotSupportedException();
1091 }
1092
1093 /**
1094 * Helper class for auto-numbering platform threads. The numbers start at
1095 * 0 and are separate from the thread identifier for historical reasons.
1096 */
1097 private static class ThreadNumbering {
1419 public Thread(ThreadGroup group, Runnable task, String name,
1420 long stackSize, boolean inheritInheritableThreadLocals) {
1421 this(group, checkName(name),
1422 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1423 task, stackSize);
1424 }
1425
1426 /**
1427 * Creates a virtual thread to execute a task and schedules it to execute.
1428 *
1429 * <p> This method is equivalent to:
1430 * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1431 *
1432 * @param task the object to run when the thread executes
1433 * @return a new, and started, virtual thread
1434 * @see <a href="#inheritance">Inheritance when creating threads</a>
1435 * @since 21
1436 */
1437 public static Thread startVirtualThread(Runnable task) {
1438 Objects.requireNonNull(task);
1439 var thread = ThreadBuilders.newVirtualThread(null, null, 0, task);
1440 thread.start();
1441 return thread;
1442 }
1443
1444 /**
1445 * Returns {@code true} if this thread is a virtual thread. A virtual thread
1446 * is scheduled by the Java virtual machine rather than the operating system.
1447 *
1448 * @return {@code true} if this thread is a virtual thread
1449 *
1450 * @since 21
1451 */
1452 public final boolean isVirtual() {
1453 return (this instanceof BaseVirtualThread);
1454 }
1455
1456 /**
1457 * Schedules this thread to begin execution. The thread will execute
1458 * independently of the current thread.
1459 *
|
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.misc.TerminatingThreadLocal;
42 import jdk.internal.misc.Unsafe;
43 import jdk.internal.misc.VM;
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 static java.util.concurrent.TimeUnit.MILLISECONDS;
54 import static java.util.concurrent.TimeUnit.NANOSECONDS;
55
56 /**
57 * A <i>thread</i> is a thread of execution in a program. The Java
58 * virtual machine allows an application to have multiple threads of
723 static {
724 U = Unsafe.getUnsafe();
725 NEXT_TID_OFFSET = Thread.getNextThreadIdOffset();
726 }
727 static long next() {
728 return U.getAndAddLong(null, NEXT_TID_OFFSET, 1);
729 }
730 }
731
732 /**
733 * Initializes a platform Thread.
734 *
735 * @param g the Thread group, can be null
736 * @param name the name of the new Thread
737 * @param characteristics thread characteristics
738 * @param task the object whose run() method gets called
739 * @param stackSize the desired stack size for the new thread, or
740 * zero to indicate that this parameter is to be ignored.
741 */
742 Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
743 Thread parent = currentThread();
744 boolean attached = (parent == this); // primordial or JNI attached
745
746 if (attached) {
747 if (g == null) {
748 throw new InternalError("group cannot be null when attaching");
749 }
750 this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
751 } else {
752 if (g == null) {
753 // default to current thread's group
754 g = parent.getThreadGroup();
755 }
756 int priority = Math.min(parent.getPriority(), g.getMaxPriority());
757 this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
758 }
759
760 if (attached && VM.initLevel() < 1) {
761 this.tid = PRIMORDIAL_TID; // primordial thread
762 } else {
806 }
807 this.contextClassLoader = parent.getContextClassLoader();
808 } else {
809 // default CCL to the system class loader when not inheriting
810 this.contextClassLoader = ClassLoader.getSystemClassLoader();
811 }
812
813 // special value to indicate this is a newly-created Thread
814 this.scopedValueBindings = NEW_THREAD_BINDINGS;
815
816 // create a FieldHolder object, needed when bound to an OS thread
817 if (bound) {
818 ThreadGroup g = Constants.VTHREAD_GROUP;
819 int pri = NORM_PRIORITY;
820 this.holder = new FieldHolder(g, null, -1, pri, true);
821 } else {
822 this.holder = null;
823 }
824 }
825
826 /**
827 * The task that a {@linkplain VirtualThreadScheduler virtual thread scheduler}
828 * executes on a platform thread to
829 * {@linkplain VirtualThreadScheduler#onStart(VirtualThreadTask) start}
830 * or {@linkplain VirtualThreadScheduler#onContinue(VirtualThreadTask) continue}
831 * execution of a virtual thread. While executing the task, the platform thread is
832 * the virtual thread's <em>carrier</em>.
833 *
834 * <p> There is a {@code VirtualThreadTask} object for each virtual thread. The
835 * scheduler arranges to execute its {@link #run()} method when called to start or
836 * continue the virtual thread, if possible on the {@linkplain #preferredCarrier()
837 * preferred carrier thread}. The scheduler may attach an object to the task.
838 *
839 * @since 99
840 */
841 public sealed interface VirtualThreadTask extends Runnable permits VirtualThread.VThreadTask {
842
843 /**
844 * {@return the virtual thread that this task starts or continues}
845 */
846 Thread thread();
847
848 /**
849 * Runs the task on the current thread as the carrier thread.
850 *
851 * <p> Invoking this method with the interrupted status set will first
852 * clear the interrupt status. Interrupting the carrier thread while
853 * running the task leads to unspecified behavior.
854 *
855 * @throws IllegalStateException if the virtual thread is not in a state to
856 * run on the current thread
857 * @throws IllegalCallerException if the current thread is a virtual thread
858 */
859 @Override
860 void run();
861
862 /**
863 * Returns the preferred carrier thread to execute this task. The scheduler may
864 * choose to ignore this preference.
865 * @return the preferred carrier thread or {@code null} if there is no preferred
866 * carrier thread
867 */
868 Thread preferredCarrier();
869
870 /**
871 * Attaches the given object to this task.
872 * @param att the object to attach
873 * @return the previously-attached object, if any, otherwise {@code null}
874 */
875 Object attach(Object att);
876
877 /**
878 * Retrieves the current attachment.
879 * @return the object currently attached to this task or {@code null} if
880 * there is no attachment
881 */
882 Object attachment();
883 }
884
885 /**
886 * Virtual thread scheduler.
887 *
888 * @apiNote The following example creates a virtual thread scheduler that uses a small
889 * set of platform threads.
890 * {@snippet lang=java :
891 * ExecutorService threadPool = Executors.newFixedThreadPool(4);
892 * var scheduler = new VirtualThreadScheduler() {
893 * private void submit(VirtualThreadTask task) {
894 * Thread caller = Thread.currentThread();
895 * threadPool.submit(() -> {
896 * Thread vthread = task.thread();
897 * Thread carrier = Thread.currentThread();
898 * try {
899 * task.run();
900 * } finally {
901 * assert Thread.currentThread() == carrier;
902 * boolean terminated = !vthread.isAlive();
903 * }
904 * });
905 * }
906 * @Override
907 * public void onStart(VirtualThreadTask task) {
908 * submit(task);
909 * }
910 * @Override
911 * public void onContinue(VirtualThreadTask task) {
912 * submit(task);
913 * }
914 * };
915 * }
916 *
917 * <p> Unless otherwise specified, passing a null argument to a method in
918 * this interface causes a {@code NullPointerException} to be thrown.
919 *
920 * @since 99
921 */
922 public interface VirtualThreadScheduler {
923 /**
924 * Invoked by {@link Thread#start()} to start execution of a {@linkplain
925 * VirtualThreadTask#thread() virtual thread}.
926 * The scheduler's implementation of this method must arrange to execute the
927 * given task's {@link VirtualThreadTask#run() run()} method on a platform thread.
928 *
929 * @implNote If invoked from a virtual thread, then the caller virtual thread is
930 * <em>pinned</em> to its carrier while executing the {@code onStart} method.
931 *
932 * @param task the task to execute
933 * @throws RejectedExecutionException if the scheduler cannot accept the task
934 */
935 void onStart(VirtualThreadTask task);
936
937 /**
938 * Invoked to continue execution of a {@linkplain VirtualThreadTask#thread()
939 * virtual thread}.
940 * The scheduler's implementation of this method must arrange to execute the
941 * given task's {@link VirtualThreadTask#run() run()} method on a platform thread.
942 *
943 * @implNote If invoked from a virtual thread, then the caller virtual thread is
944 * <em>pinned</em> to its carrier while executing the {@code onContinue} method.
945 *
946 * @param task the task to execute
947 * @throws RejectedExecutionException if the scheduler cannot accept the task
948 */
949 void onContinue(VirtualThreadTask task);
950
951 /**
952 * Creates a new virtual thread, returning the {@code VirtualThreadTask} that the
953 * virtual thread scheduler arranges to execute on a platform thread to start or
954 * continue execution of the virtual thread.
955 *
956 * <p> This method creates a new unstarted {@code Thread} from the current state
957 * of the given builder to run the given task. The {@link VirtualThreadTask#thread()
958 * thread()} method returns the virtual threa. The thread's {@link Thread#start()
959 * start()} method must be invoked to schedule the thread to begin execution.
960 *
961 * @apiNote This method is intended for frameworks that make use of a custom
962 * {@link VirtualThreadScheduler VirtualThreadScheduler} and wish to specify a
963 * preferred carrier thread when creating a virtual thread, or need a reference
964 * to the virtual thread task before the virtual thread is started. The
965 * framework can use the {@link VirtualThreadTask#attach(Object) attach(Object)}
966 * method to attach its context object to the task before the thread is started.
967 *
968 * @implSpec The default implementation creates a new virtual thread. It should
969 * be rare to override this method.
970 *
971 * @param builder the virtual thread builder
972 * @param preferredCarrier the preferred carrirer, can be {@code null}
973 * @param task the object to run when the thread executes
974 * @return the {@code VirtualThreadTask} that scheduler executes
975 * @throws UnsupportedOperationException if this is the built-in default scheduler
976 *
977 * @see <a href="Thread.html#inheritance">Inheritance when creating threads</a>
978 */
979 default VirtualThreadTask newThread(Builder.OfVirtual builder,
980 Thread preferredCarrier,
981 Runnable task) {
982 Objects.requireNonNull(builder);
983 Objects.requireNonNull(task);
984 if (this == VirtualThread.builtinScheduler(false)) {
985 throw new UnsupportedOperationException();
986 }
987 var vbuilder = (ThreadBuilders.VirtualThreadBuilder) builder;
988 var vthread = (VirtualThread) vbuilder.unstarted(task, preferredCarrier);
989 return vthread.virtualThreadTask();
990 }
991
992 /**
993 * Schedules a task that becomes enabled for execution after the given delay.
994 *
995 * <p> This method is invoked to schedule delayed tasks in support of timed
996 * operations and methods such as {@link Thread#sleep(long)} and {@link
997 * Object#wait(long)}. The scheduler should arrange to execute the task on
998 * a platform thread.
999 *
1000 * @implSpec The default implementation schedules the task to execute after
1001 * the given delay. The task executes on JDK internal thread. An implementation
1002 * may wish to override this method when it is capable of scheduling delayed
1003 * tasks.
1004 *
1005 * @param task the task to execute
1006 * @param delay the time from now to delay execution
1007 * @param unit the time unit of the delay parameter
1008 * @return a Future representing pending completion of the task
1009 */
1010 default Future<?> schedule(Runnable task, long delay, TimeUnit unit) {
1011 return VirtualThread.DelayedTaskSchedulers.schedule(task, delay, unit);
1012 }
1013 }
1014
1015 /**
1016 * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
1017 * that creates platform threads.
1018 *
1019 * @apiNote The following are examples using the builder:
1020 * {@snippet :
1021 * // Start a daemon thread to run a task
1022 * Thread thread = Thread.ofPlatform().daemon().start(runnable);
1023 *
1024 * // Create an unstarted thread with name "duke", its start() method
1025 * // must be invoked to schedule it to execute.
1026 * Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
1027 *
1028 * // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
1029 * ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
1030 * }
1031 *
1032 * @return A builder for creating {@code Thread} or {@code ThreadFactory} objects.
1033 * @since 21
1034 */
1249 * that creates virtual threads.
1250 *
1251 * <p> Unless otherwise specified, passing a null argument to a method in
1252 * this interface causes a {@code NullPointerException} to be thrown.
1253 *
1254 * @see Thread#ofVirtual()
1255 * @since 21
1256 */
1257 sealed interface OfVirtual extends Builder
1258 permits ThreadBuilders.VirtualThreadBuilder {
1259
1260 @Override OfVirtual name(String name);
1261
1262 /**
1263 * @throws IllegalArgumentException {@inheritDoc}
1264 */
1265 @Override OfVirtual name(String prefix, long start);
1266
1267 @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
1268 @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
1269
1270 /**
1271 * Creates a new {@code Thread} from the current state of the builder and
1272 * schedules it without guaranteeing that it will eventually execute.
1273 *
1274 * @param task the object to run when the thread executes
1275 * @return a new started Thread
1276 *
1277 * @see <a href="Thread.html#inheritance">Inheritance when creating threads</a>
1278 * @since 99
1279 */
1280 Thread lazyStart(Runnable task);
1281 }
1282 }
1283
1284 /**
1285 * Throws CloneNotSupportedException as a Thread can not be meaningfully
1286 * cloned. Construct a new Thread instead.
1287 *
1288 * @throws CloneNotSupportedException
1289 * always
1290 */
1291 @Override
1292 protected Object clone() throws CloneNotSupportedException {
1293 throw new CloneNotSupportedException();
1294 }
1295
1296 /**
1297 * Helper class for auto-numbering platform threads. The numbers start at
1298 * 0 and are separate from the thread identifier for historical reasons.
1299 */
1300 private static class ThreadNumbering {
1622 public Thread(ThreadGroup group, Runnable task, String name,
1623 long stackSize, boolean inheritInheritableThreadLocals) {
1624 this(group, checkName(name),
1625 (inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
1626 task, stackSize);
1627 }
1628
1629 /**
1630 * Creates a virtual thread to execute a task and schedules it to execute.
1631 *
1632 * <p> This method is equivalent to:
1633 * <pre>{@code Thread.ofVirtual().start(task); }</pre>
1634 *
1635 * @param task the object to run when the thread executes
1636 * @return a new, and started, virtual thread
1637 * @see <a href="#inheritance">Inheritance when creating threads</a>
1638 * @since 21
1639 */
1640 public static Thread startVirtualThread(Runnable task) {
1641 Objects.requireNonNull(task);
1642 var thread = ThreadBuilders.newVirtualThread(null, 0, task);
1643 thread.start();
1644 return thread;
1645 }
1646
1647 /**
1648 * Returns {@code true} if this thread is a virtual thread. A virtual thread
1649 * is scheduled by the Java virtual machine rather than the operating system.
1650 *
1651 * @return {@code true} if this thread is a virtual thread
1652 *
1653 * @since 21
1654 */
1655 public final boolean isVirtual() {
1656 return (this instanceof BaseVirtualThread);
1657 }
1658
1659 /**
1660 * Schedules this thread to begin execution. The thread will execute
1661 * independently of the current thread.
1662 *
|