< prev index next >

src/java.base/share/classes/java/lang/Thread.java

Print this page

 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
< prev index next >