145 * Runnable runnable = ...
146 *
147 * // Start a daemon thread to run a task
148 * Thread thread = Thread.ofPlatform().daemon().start(runnable);
149 *
150 * // Create an unstarted thread with name "duke", its start() method
151 * // must be invoked to schedule it to execute.
152 * Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
153 *
154 * // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
155 * ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
156 *
157 * // Start a virtual thread to run a task
158 * Thread thread = Thread.ofVirtual().start(runnable);
159 *
160 * // A ThreadFactory that creates virtual threads
161 * ThreadFactory factory = Thread.ofVirtual().factory();
162 * }
163 *
164 * <h2><a id="inheritance">Inheritance when creating threads</a></h2>
165 * 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> Platform threads inherit the daemon status, thread priority, and when not
175 * provided (or not selected by a security manager), the thread group.
176 *
177 * <p> Creating a platform thread {@linkplain AccessController#getContext() captures} the
178 * {@linkplain AccessControlContext caller context} to limit the {@linkplain Permission
179 * permissions} of the new thread when it executes code that performs a {@linkplain
180 * AccessController#doPrivileged(PrivilegedAction) privileged action}. The captured
181 * caller context is the new thread's "Inherited {@link AccessControlContext}". Creating
182 * a virtual thread does not capture the caller context; virtual threads have no
183 * permissions when executing code that performs a privileged action.
184 *
185 * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
186 * or method in this class will cause a {@link NullPointerException} to be thrown.
187 *
188 * @implNote
189 * In the JDK Reference Implementation, the virtual thread scheduler may be configured
190 * with the following system properties:
191 * <table class="striped">
192 * <caption style="display:none">System properties</caption>
193 * <thead>
194 * <tr>
195 * <th scope="col">System property</th>
196 * <th scope="col">Description</th>
704
705 // default to current thread's group
706 if (g == null) {
707 g = parent.getThreadGroup();
708 }
709 }
710
711 // permission checks when creating a child Thread
712 if (sm != null) {
713 sm.checkAccess(g);
714 if (isCCLOverridden(getClass())) {
715 sm.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
716 }
717 }
718
719 int priority = Math.min(parent.getPriority(), g.getMaxPriority());
720 this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
721 }
722
723 if (attached && VM.initLevel() < 1) {
724 this.tid = 1; // primordial thread
725 } else {
726 this.tid = ThreadIdentifiers.next();
727 }
728 this.name = (name != null) ? name : genThreadName();
729
730 if (acc != null) {
731 this.inheritedAccessControlContext = acc;
732 } else {
733 this.inheritedAccessControlContext = AccessController.getContext();
734 }
735
736 // thread locals
737 if (!attached) {
738 if ((characteristics & NO_INHERIT_THREAD_LOCALS) == 0) {
739 ThreadLocal.ThreadLocalMap parentMap = parent.inheritableThreadLocals;
740 if (parentMap != null && parentMap.size() > 0) {
741 this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
742 }
743 if (VM.isBooted()) {
744 this.contextClassLoader = contextClassLoader(parent);
745 }
746 } else if (VM.isBooted()) {
747 // default CCL to the system class loader when not inheriting
|
145 * Runnable runnable = ...
146 *
147 * // Start a daemon thread to run a task
148 * Thread thread = Thread.ofPlatform().daemon().start(runnable);
149 *
150 * // Create an unstarted thread with name "duke", its start() method
151 * // must be invoked to schedule it to execute.
152 * Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
153 *
154 * // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
155 * ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
156 *
157 * // Start a virtual thread to run a task
158 * Thread thread = Thread.ofVirtual().start(runnable);
159 *
160 * // A ThreadFactory that creates virtual threads
161 * ThreadFactory factory = Thread.ofVirtual().factory();
162 * }
163 *
164 * <h2><a id="inheritance">Inheritance when creating threads</a></h2>
165 * A {@code Thread} created with one of the public constructors inherits the daemon
166 * status and thread priority from the parent thread at the time that the child {@code
167 * Thread} is created. The {@linkplain ThreadGroup thread group} is also inherited when
168 * not provided to the constructor (and not selected by the security manager).
169 * When using a {@code Thread.Builder} to create a platform thread, the daemon status,
170 * thread priority, and thread group (when not selected by the security manager) are
171 * inherited when not set on the builder. As with the constructors, inheriting from the
172 * parent thread is done when the child {@code Thread} is created.
173 *
174 * <p> A {@code Thread} inherits its initial values of {@linkplain InheritableThreadLocal
175 * inheritable-thread-local} variables (including the context class loader) from
176 * the parent thread values at the time that the child {@code Thread} is created.
177 * The 5-param {@linkplain Thread#Thread(ThreadGroup, Runnable, String, long, boolean)
178 * constructor} can be used to create a thread that does not inherit its initial
179 * values from the constructing thread. When using a {@code Thread.Builder}, the
180 * {@link Builder#inheritInheritableThreadLocals(boolean) inheritInheritableThreadLocals}
181 * method can be used to select if the initial values are inherited.
182 *
183 * <p> Creating a platform thread {@linkplain AccessController#getContext() captures} the
184 * {@linkplain AccessControlContext caller context} to limit the {@linkplain Permission
185 * permissions} of the new thread when it executes code that performs a {@linkplain
186 * AccessController#doPrivileged(PrivilegedAction) privileged action}. The captured
187 * caller context is the new thread's "Inherited {@link AccessControlContext}". Creating
188 * a virtual thread does not capture the caller context; virtual threads have no
189 * permissions when executing code that performs a privileged action.
190 *
191 * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
192 * or method in this class will cause a {@link NullPointerException} to be thrown.
193 *
194 * @implNote
195 * In the JDK Reference Implementation, the virtual thread scheduler may be configured
196 * with the following system properties:
197 * <table class="striped">
198 * <caption style="display:none">System properties</caption>
199 * <thead>
200 * <tr>
201 * <th scope="col">System property</th>
202 * <th scope="col">Description</th>
710
711 // default to current thread's group
712 if (g == null) {
713 g = parent.getThreadGroup();
714 }
715 }
716
717 // permission checks when creating a child Thread
718 if (sm != null) {
719 sm.checkAccess(g);
720 if (isCCLOverridden(getClass())) {
721 sm.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
722 }
723 }
724
725 int priority = Math.min(parent.getPriority(), g.getMaxPriority());
726 this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
727 }
728
729 if (attached && VM.initLevel() < 1) {
730 this.tid = 3; // primordial thread
731 } else {
732 this.tid = ThreadIdentifiers.next();
733 }
734
735 this.name = (name != null) ? name : genThreadName();
736
737 if (acc != null) {
738 this.inheritedAccessControlContext = acc;
739 } else {
740 this.inheritedAccessControlContext = AccessController.getContext();
741 }
742
743 // thread locals
744 if (!attached) {
745 if ((characteristics & NO_INHERIT_THREAD_LOCALS) == 0) {
746 ThreadLocal.ThreadLocalMap parentMap = parent.inheritableThreadLocals;
747 if (parentMap != null && parentMap.size() > 0) {
748 this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
749 }
750 if (VM.isBooted()) {
751 this.contextClassLoader = contextClassLoader(parent);
752 }
753 } else if (VM.isBooted()) {
754 // default CCL to the system class loader when not inheriting
|