< prev index next > src/java.base/share/classes/java/lang/Thread.java
Print this page
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
*
* <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>
*
* <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>
* <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>
*
* <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>
*
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,
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;
* @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) {
} 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:
*/
@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
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 >