< prev index next >

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

Print this page
*** 29,26 ***
--- 29,31 ---
  import java.lang.reflect.Field;
  import java.time.Duration;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Objects;
+ import java.util.concurrent.Executor;
  import java.util.concurrent.ThreadFactory;
  import java.util.concurrent.StructureViolationException;
  import java.util.concurrent.locks.LockSupport;
  import jdk.internal.event.ThreadSleepEvent;
+ import jdk.internal.javac.Restricted;
  import jdk.internal.misc.TerminatingThreadLocal;
  import jdk.internal.misc.Unsafe;
  import jdk.internal.misc.VM;
+ import jdk.internal.reflect.CallerSensitive;
  import jdk.internal.vm.Continuation;
  import jdk.internal.vm.ScopedValueContainer;
  import jdk.internal.vm.StackableScope;
  import jdk.internal.vm.ThreadContainer;
  import jdk.internal.vm.annotation.ForceInline;
  import jdk.internal.vm.annotation.Hidden;
  import jdk.internal.vm.annotation.IntrinsicCandidate;
  import jdk.internal.vm.annotation.Stable;
  import sun.nio.ch.Interruptible;
+ import sun.nio.ch.NativeThread;
+ 
  import static java.util.concurrent.TimeUnit.MILLISECONDS;
  import static java.util.concurrent.TimeUnit.NANOSECONDS;
  
  /**
   * A <i>thread</i> is a thread of execution in a program. The Java

*** 173,12 ***
   *
   * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
   * or method in this class will cause a {@link NullPointerException} to be thrown.
   *
   * @implNote
!  * In the JDK Reference Implementation, the virtual thread scheduler may be configured
!  * with the following system properties:
   * <table class="striped">
   * <caption style="display:none">System properties</caption>
   *   <thead>
   *   <tr>
   *     <th scope="col">System property</th>
--- 178,12 ---
   *
   * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
   * or method in this class will cause a {@link NullPointerException} to be thrown.
   *
   * @implNote
!  * In the JDK Reference Implementation, the following system properties may be used to
!  * configure the default virtual thread scheduler:
   * <table class="striped">
   * <caption style="display:none">System properties</caption>
   *   <thead>
   *   <tr>
   *     <th scope="col">System property</th>

*** 188,18 ***
   *   <tbody>
   *   <tr>
   *     <th scope="row">
   *       {@systemProperty jdk.virtualThreadScheduler.parallelism}
   *     </th>
!  *     <td> The number of platform threads available for scheduling virtual
!  *       threads. It defaults to the number of available processors. </td>
   *   </tr>
   *   <tr>
   *     <th scope="row">
   *       {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
   *     </th>
!  *     <td> The maximum number of platform threads available to the scheduler.
   *       It defaults to 256. </td>
   *   </tr>
   *   </tbody>
   * </table>
   *
--- 193,18 ---
   *   <tbody>
   *   <tr>
   *     <th scope="row">
   *       {@systemProperty jdk.virtualThreadScheduler.parallelism}
   *     </th>
!  *     <td> The default scheduler's target parallelism. It defaults to the number of
!  *       available processors. </td>
   *   </tr>
   *   <tr>
   *     <th scope="row">
   *       {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
   *     </th>
!  *     <td> The maximum number of platform threads available to the default scheduler.
   *       It defaults to 256. </td>
   *   </tr>
   *   </tbody>
   * </table>
   *

*** 242,10 ***
--- 247,13 ---
          final long stackSize;
          volatile int priority;
          volatile boolean daemon;
          volatile int threadStatus;
  
+         // Native thread used for signalling, set lazily, read from any thread
+         volatile NativeThread nativeThread;
+ 
          // This map is maintained by the ThreadLocal class
          ThreadLocal.ThreadLocalMap terminatingThreadLocals;
  
          FieldHolder(ThreadGroup group,
                      Runnable task,

*** 268,10 ***
--- 276,18 ---
  
      void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) {
          holder.terminatingThreadLocals = map;
      }
  
+     NativeThread nativeThread() {
+         return holder.nativeThread;
+     }
+ 
+     void setNativeThread(NativeThread nt) {
+         holder.nativeThread = nt;
+     }
+ 
      /*
       * ThreadLocal values pertaining to this thread. This map is maintained
       * by the ThreadLocal class.
       */
      private ThreadLocal.ThreadLocalMap threadLocals;

*** 682,11 ***
       * @param task the object whose run() method gets called
       * @param stackSize the desired stack size for the new thread, or
       *        zero to indicate that this parameter is to be ignored.
       */
      Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
- 
          Thread parent = currentThread();
          boolean attached = (parent == this);   // primordial or JNI attached
  
          if (attached) {
              if (g == null) {
--- 698,10 ---

*** 766,10 ***
--- 781,91 ---
          } else {
              this.holder = null;
          }
      }
  
+     /**
+      * The task {@link java.util.concurrent.Executor#execute(Runnable) submitted} to
+      * a user-provided {@link Thread.Builder.OfVirtual#scheduler(Executor) scheduler}.
+      *
+      * @apiNote The following example creates a scheduler that uses a small set of
+      * platform threads.
+      * <pre>{@code
+      *     ExecutorService pool = Executors.newFixedThreadPool(4);
+      *     Executor scheduler = (task) -> {
+      *         // invoke pool.execute in the context of the caller
+      *         pool.execute(() -> {
+      *             Thread carrier = Thread.currentThread();
+      *             Thread vthread = ((Thread.VirtualThreadTask) task).thread();
+      *
+      *             // runs virtual thread task
+      *             task.run();
+      *
+      *             assert Thread.currentThread() == carrier;
+      *         }));
+      *     };
+      * }</pre>
+      *
+      * @see Thread.Builder.OfVirtual#scheduler(Executor)
+      * @since 99
+      */
+     public interface VirtualThreadTask extends Runnable {
+ 
+         /**
+          * Return the virtual thread that this task was submitted to run
+          * @return the virtual thread
+          */
+         Thread thread();
+ 
+         /**
+          * Attaches the given object to this task.
+          * @param att the object to attach
+          * @return the previously-attached object, if any, otherwise {@code null}
+          */
+         Object attach(Object att);
+ 
+         /**
+          * Retrieves the current attachment.
+          * @return the object currently attached to this task or {@code null} if
+          *         there is no attachment
+          */
+         Object attachment();
+ 
+         /**
+          * Returns the object currently attached to the {@code VirtualThreadTask} for
+          * the current virtual thread.
+          * @return the object currently attached to current virtual thread's task
+          * @throws IllegalCallerException if the current thread is a platform thread
+          */
+         static Object currentVirtualThreadTaskAttachment() {
+             Thread t = Thread.currentThread();
+             if (t instanceof VirtualThread vthread) {
+                 return vthread.currentTaskAttachment();
+             } else if (t.isVirtual()) {
+                 // not supported with BoundVirtualThread
+                 return null;
+             } else {
+                 // platform thread
+                 throw new IllegalCallerException();
+             }
+         }
+ 
+         /**
+          * Runs the task on the current thread as the carrier thread.
+          *
+          * <p> Invoking this method with the interrupt status set will first
+          * clear the interrupt status. Interrupting the carrier thread while
+          * running the task leads to unspecified behavior.
+          *
+          * @throws IllegalStateException if the virtual thread is not in a state to
+          *         run on the current thread
+          * @throws IllegalCallerException if the current thread is a virtual thread
+          */
+         @Override
+         void run();
+     }
+ 
      /**
       * Returns a builder for creating a platform {@code Thread} or {@code ThreadFactory}
       * that creates platform threads.
       *
       * @apiNote The following are examples using the builder:

*** 1020,10 ***
--- 1116,32 ---
               */
              @Override OfVirtual name(String prefix, long start);
  
              @Override OfVirtual inheritInheritableThreadLocals(boolean inherit);
              @Override OfVirtual uncaughtExceptionHandler(UncaughtExceptionHandler ueh);
+ 
+             /**
+              * Sets the scheduler.
+              * The thread will be scheduled by the Java virtual machine with the given
+              * scheduler. The scheduler's {@link Executor#execute(Runnable) execute}
+              * method is invoked with tasks of type {@link Thread.VirtualThreadTask}. It
+              * may be invoked in the context of a virtual thread. The scheduler should
+              * arrange to execute these tasks on a platform thread. Attempting to execute
+              * the task on a virtual thread causes an exception to be thrown (see
+              * {@link Thread.VirtualThreadTask#run() VirtualThreadTask.run}). The {@code
+              * execute} method may be invoked at sensitive times (e.g. when unparking a
+              * thread) so care should be taken to not directly execute the task on the
+              * <em>current thread</em>.
+              *
+              * @param scheduler the scheduler
+              * @return this builder
+              * @throws UnsupportedOperationException if scheduling virtual threads to a
+              *         user-provided scheduler is not supported by this VM
+              */
+             @CallerSensitive
+             @Restricted
+             OfVirtual scheduler(Executor scheduler);
          }
      }
  
      /**
       * Throws CloneNotSupportedException as a Thread can not be meaningfully

*** 1370,10 ***
--- 1488,11 ---
                  task, stackSize);
      }
  
      /**
       * Creates a virtual thread to execute a task and schedules it to execute.
+      * The thread is scheduled to the default virtual thread scheduler.
       *
       * <p> This method is equivalent to:
       * <pre>{@code Thread.ofVirtual().start(task); }</pre>
       *
       * @param task the object to run when the thread executes
< prev index next >