< prev index next >

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

Print this page
*** 29,26 ***
--- 29,32 ---
  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.reflect.Reflection;
  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>
--- 179,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 built-in 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>
   *
--- 194,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 ***
--- 248,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 ***
--- 277,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) {
--- 699,10 ---

*** 766,10 ***
--- 782,77 ---
          } else {
              this.holder = null;
          }
      }
  
+     /**
+      * Virtual thread scheduler.
+      *
+      * @apiNote The following example creates a virtual thread scheduler that uses a small
+      * set of platform threads.
+      * {@snippet lang=java :
+      *     ExecutorService pool = Executors.newFixedThreadPool(4);
+      *     VirtualThreadScheduler scheduler = (vthread, task) -> {
+      *          pool.submit(() -> {
+      *              Thread carrier = Thread.currentThread();
+      *
+      *              // runs the virtual thread task
+      *              task.run();
+      *
+      *              assert Thread.currentThread() == carrier;
+      *         });
+      *     };
+      * }
+      *
+      * <p> Unless otherwise specified, passing a null argument to a method in
+      * this interface causes a {@code NullPointerException} to be thrown.
+      *
+      * @see Builder.OfVirtual#scheduler(VirtualThreadScheduler)
+      * @since 99
+      */
+     @FunctionalInterface
+     public interface VirtualThreadScheduler {
+         /**
+          * Continue execution of given virtual thread by executing the given task on
+          * a platform thread.
+          *
+          * @param vthread the virtual thread
+          * @param task the task to execute
+          */
+         void execute(Thread vthread, Runnable task);
+ 
+         /**
+          * {@return a virtual thread scheduler that delegates tasks to the given executor}
+          * @param executor the executor
+          */
+         static VirtualThreadScheduler adapt(Executor executor) {
+             Objects.requireNonNull(executor);
+             return (_, task) -> executor.execute(task);
+         }
+ 
+         /**
+          * {@return the virtual thread scheduler for the current virtual thread}
+          * @throws UnsupportedOperationException if the current thread is not a virtual
+          * thread or scheduling virtual threads to a user-provided scheduler is not
+          * supported by this VM
+          */
+         @CallerSensitive
+         @Restricted
+         static VirtualThreadScheduler current() {
+             Class<?> caller = Reflection.getCallerClass();
+             caller.getModule().ensureNativeAccess(VirtualThreadScheduler.class,
+                     "current",
+                     caller,
+                     false);
+             if (Thread.currentThread() instanceof VirtualThread vthread) {
+                 return vthread.scheduler(false);
+             } else {
+                 throw new UnsupportedOperationException();
+             }
+         }
+     }
+ 
      /**
       * 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 ***
--- 1103,35 ---
               */
              @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 VirtualThreadScheduler#execute(Thread, Runnable)}
+              * method may be invoked in the context of a virtual thread. The scheduler
+              * must arrange to execute the {@code Runnable}'s {@code run} method on a
+              * platform thread. Attempting to execute the run method in a virtual thread
+              * causes {@link WrongThreadException} to be thrown.
+              *
+              * 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
+              *
+              * @since 99
+              */
+             @CallerSensitive
+             @Restricted
+             OfVirtual scheduler(VirtualThreadScheduler scheduler);
          }
      }
  
      /**
       * Throws CloneNotSupportedException as a Thread can not be meaningfully

*** 1370,10 ***
--- 1478,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 >