< prev index next >

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

Print this page

        

*** 36,45 **** --- 36,46 ---- import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; + import jdk.internal.misc.Strands; import jdk.internal.misc.TerminatingThreadLocal; import sun.nio.ch.Interruptible; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import sun.security.util.SecurityConstants;
*** 196,205 **** --- 197,211 ---- /* * Thread ID */ private final long tid; + /* + * Current inner-most continuation + */ + private Continuation cont; + /* For generating thread ID */ private static long threadSeqNumber; private static synchronized long nextThreadID() { return ++threadSeqNumber;
*** 233,242 **** --- 239,260 ---- synchronized (me.blockerLock) { me.blocker = b; } } + Object blockerLock() { + return blockerLock; + } + + void runInterrupter() { + assert Thread.holdsLock(blockerLock); + Interruptible b = blocker; + if (b != null) { + b.interrupt(this); + } + } + /** * The minimum priority that a thread can have. */ public static final int MIN_PRIORITY = 1;
*** 249,264 **** * The maximum priority that a thread can have. */ public static final int MAX_PRIORITY = 10; /** ! * Returns a reference to the currently executing thread object. * ! * @return the currently executing thread. */ @HotSpotIntrinsicCandidate ! public static native Thread currentThread(); /** * A hint to the scheduler that the current thread is willing to yield * its current use of a processor. The scheduler is free to ignore this * hint. --- 267,335 ---- * The maximum priority that a thread can have. */ public static final int MAX_PRIORITY = 10; /** ! * Returns the Thread object for the current thread. * ! * <p> When executed in the context of a fiber, the returned Thread object ! * does not support all features of Thread. In particular, the Thread ! * is not an <i>active thread</i> in its thread group and so is not enumerated ! * or acted on by thread group operations. In addition it does not support ! * the stop, suspend or resume methods. ! * ! * @return the current thread ! */ ! public static Thread currentThread() { ! Thread t = currentThread0(); ! Fiber<?> fiber = t.fiber; ! if (fiber != null) { ! return fiber.shadowThread(); ! } else { ! return t; ! } ! } ! ! /** ! * Returns the current carrier thread. */ + static Thread currentCarrierThread() { + return currentThread0(); + } + @HotSpotIntrinsicCandidate ! private static native Thread currentThread0(); ! ! private Fiber<?> fiber; ! private FiberScope scope; ! ! /** ! * Binds this thread to given Fiber. Once set, Thread.currentThread() will ! * return the Fiber rather than the Thread object for the carrier thread. ! */ ! void setFiber(Fiber<?> fiber) { ! //assert this == currentThread0(); ! this.fiber = fiber; ! } ! ! /** ! * Returns the Fiber that is currently bound to this thread. ! */ ! Fiber<?> getFiber() { ! //assert this == currentThread0(); ! return fiber; ! } ! ! FiberScope scope() { ! assert Thread.currentThread() == this; ! return scope; ! } ! ! void setScope(FiberScope scope) { ! assert Thread.currentThread() == this; ! this.scope = scope; ! } /** * A hint to the scheduler that the current thread is willing to yield * its current use of a processor. The scheduler is free to ignore this * hint.
*** 272,282 **** * for debugging or testing purposes, where it may help to reproduce * bugs due to race conditions. It may also be useful when designing * concurrency control constructs such as the ones in the * {@link java.util.concurrent.locks} package. */ ! public static native void yield(); /** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. The thread --- 343,361 ---- * for debugging or testing purposes, where it may help to reproduce * bugs due to race conditions. It may also be useful when designing * concurrency control constructs such as the ones in the * {@link java.util.concurrent.locks} package. */ ! public static void yield() { ! Fiber<?> fiber = currentCarrierThread().getFiber(); ! if (fiber != null) { ! fiber.yield(); ! } else { ! yield0(); ! } ! } ! private static native void yield0(); /** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. The thread
*** 291,301 **** * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public static native void sleep(long millis) throws InterruptedException; /** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds plus the specified * number of nanoseconds, subject to the precision and accuracy of system --- 370,390 ---- * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public static void sleep(long millis) throws InterruptedException { ! if (millis < 0) { ! throw new IllegalArgumentException("timeout value is negative"); ! } ! if (currentCarrierThread().getFiber() != null) { ! Fiber.sleepNanos(TimeUnit.MILLISECONDS.toNanos(millis)); ! } else { ! sleep0(millis); ! } ! } ! private static native void sleep0(long millis) throws InterruptedException; /** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds plus the specified * number of nanoseconds, subject to the precision and accuracy of system
*** 315,326 **** * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public static void sleep(long millis, int nanos) ! throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { --- 404,414 ---- * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) {
*** 450,459 **** --- 538,571 ---- /* Set thread ID */ this.tid = nextThreadID(); } /** + * Initializes a Thread to be used as a shadow thread for Fibers. + */ + Thread(ThreadGroup group, + String name, + ClassLoader contextClassLoader, + ThreadLocal.ThreadLocalMap inheritedLocals, + AccessControlContext inheritedAccessControlContext) + { + this.group = group; + this.name = name; + this.daemon = false; + this.priority = NORM_PRIORITY; + this.contextClassLoader = contextClassLoader; + if (inheritedLocals != null) { + this.inheritableThreadLocals = ThreadLocal.createInheritedMap(inheritedLocals); + } else { + this.inheritableThreadLocals = null; + } + this.inheritedAccessControlContext = inheritedAccessControlContext; + this.stackSize = 0; + this.tid = nextThreadID(); + } + + /** * Throws CloneNotSupportedException as a Thread can not be meaningfully * cloned. Construct a new Thread instead. * * @throws CloneNotSupportedException * always
*** 890,899 **** --- 1002,1013 ---- * application if the uncaught exception is an instance of * {@code ThreadDeath}. * * @throws SecurityException if the current thread cannot * modify this thread. + * @throws UnsupportedOperationException if invoked on the Thread object + * for a Fiber * @see #interrupt() * @see #checkAccess() * @see #run() * @see #start() * @see ThreadDeath
*** 926,935 **** --- 1040,1053 ---- checkAccess(); if (this != Thread.currentThread()) { security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); } } + + if (this instanceof ShadowThread) + throw new UnsupportedOperationException(); + // A zero status value corresponds to "NEW", it can't change to // not-NEW because we hold the lock. if (threadStatus != 0) { resume(); // Wake up thread if it was suspended; no-op otherwise }
*** 1012,1022 **** * {@code false} otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { ! return currentThread().isInterrupted(true); } /** * Tests whether this thread has been interrupted. The <i>interrupted * status</i> of the thread is unaffected by this method. --- 1130,1146 ---- * {@code false} otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { ! Thread thread = Thread.currentCarrierThread(); ! Fiber<?> fiber = thread.getFiber(); ! if (fiber != null) { ! return fiber.isInterrupted(true); ! } else { ! return thread.isInterrupted(true); ! } } /** * Tests whether this thread has been interrupted. The <i>interrupted * status</i> of the thread is unaffected by this method.
*** 1032,1057 **** */ public boolean isInterrupted() { return isInterrupted(false); } /** * Tests if some Thread has been interrupted. The interrupted state ! * is reset or not based on the value of ClearInterrupted that is * passed. */ @HotSpotIntrinsicCandidate ! private native boolean isInterrupted(boolean ClearInterrupted); /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return {@code true} if this thread is alive; * {@code false} otherwise. */ ! public final native boolean isAlive(); /** * Suspends this thread. * <p> * First, the {@code checkAccess} method of this thread is called --- 1156,1194 ---- */ public boolean isInterrupted() { return isInterrupted(false); } + void clearInterrupt() { + isInterrupted(true); + } + /** * Tests if some Thread has been interrupted. The interrupted state ! * is reset or not based on the value of clearInterrupted that is * passed. */ @HotSpotIntrinsicCandidate ! private native boolean isInterrupted(boolean clearInterrupted); /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return {@code true} if this thread is alive; * {@code false} otherwise. */ ! public final boolean isAlive() { ! if (this instanceof ShadowThread) { ! State state = getState(); ! assert state != State.NEW; ! return (state != State.TERMINATED); ! } else { ! return isAlive0(); ! } ! } ! private native boolean isAlive0(); /** * Suspends this thread. * <p> * First, the {@code checkAccess} method of this thread is called
*** 1061,1070 **** --- 1198,1209 ---- * If the thread is alive, it is suspended and makes no further * progress unless and until it is resumed. * * @throws SecurityException if the current thread cannot modify * this thread. + * @throws UnsupportedOperationException if invoked on the Thread object + * for a Fiber * @see #checkAccess * @deprecated This method has been deprecated, as it is * inherently deadlock-prone. If the target thread holds a lock on the * monitor protecting a critical system resource when it is suspended, no * thread can access this resource until the target thread is resumed. If
*** 1076,1085 **** --- 1215,1230 ---- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. */ @Deprecated(since="1.2") public final void suspend() { checkAccess(); + if (this instanceof ShadowThread) + throw new UnsupportedOperationException(); + suspend0(); + } + + void suspendThread() { suspend0(); } /** * Resumes a suspended thread.
*** 1091,1100 **** --- 1236,1247 ---- * If the thread is alive but suspended, it is resumed and is * permitted to make progress in its execution. * * @throws SecurityException if the current thread cannot modify this * thread. + * @throws UnsupportedOperationException if invoked on the Thread object + * for a Fiber * @see #checkAccess * @see #suspend() * @deprecated This method exists solely for use with {@link #suspend}, * which has been deprecated because it is deadlock-prone. * For more information, see
*** 1102,1111 **** --- 1249,1264 ---- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. */ @Deprecated(since="1.2") public final void resume() { checkAccess(); + if (this instanceof ShadowThread) + throw new UnsupportedOperationException(); + resume0(); + } + + void resumeThread() { resume0(); } /** * Changes the priority of this thread.
*** 1172,1182 **** if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name; ! if (threadStatus != 0) { setNativeName(name); } } /** --- 1325,1335 ---- if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name; ! if (!(this instanceof ShadowThread) && threadStatus != 0) { setNativeName(name); } } /**
*** 1285,1311 **** * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final synchronized void join(final long millis) ! throws InterruptedException { ! if (millis > 0) { ! if (isAlive()) { ! final long startTime = System.nanoTime(); ! long delay = millis; ! do { ! wait(delay); ! } while (isAlive() && (delay = millis - ! TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0); ! } ! } else if (millis == 0) { ! while (isAlive()) { ! wait(0); } - } else { - throw new IllegalArgumentException("timeout value is negative"); } } /** * Waits at most {@code millis} milliseconds plus --- 1438,1471 ---- * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final void join(long millis) throws InterruptedException { ! if (this instanceof ShadowThread) { ! Fiber<?> fiber = ((ShadowThread) this).fiber(); ! fiber.awaitInterruptibly(TimeUnit.MILLISECONDS.toNanos(millis)); ! return; ! } ! ! synchronized (this) { ! if (millis > 0) { ! if (isAlive()) { ! final long startTime = System.nanoTime(); ! long delay = millis; ! do { ! wait(delay); ! } while (isAlive() && (delay = millis - ! TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0); ! } ! } else if (millis == 0) { ! while (isAlive()) { ! wait(0); ! } ! } else { ! throw new IllegalArgumentException("timeout value is negative"); } } } /** * Waits at most {@code millis} milliseconds plus
*** 1331,1343 **** * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final synchronized void join(long millis, int nanos) ! throws InterruptedException { ! if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { --- 1491,1501 ---- * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) {
*** 1380,1390 **** } /** * Marks this thread as either a {@linkplain #isDaemon daemon} thread * or a user thread. The Java Virtual Machine exits when the only ! * threads running are all daemon threads. * * <p> This method must be invoked before the thread is started. * * @param on * if {@code true}, marks this thread as a daemon thread --- 1538,1550 ---- } /** * Marks this thread as either a {@linkplain #isDaemon daemon} thread * or a user thread. The Java Virtual Machine exits when the only ! * threads running are all daemon threads. The daemon status of {@code ! * Thread} objects associated with {@link Fiber}s is meaningless and does ! * not determine if the Java Virtual Machine exits or not. * * <p> This method must be invoked before the thread is started. * * @param on * if {@code true}, marks this thread as a daemon thread
*** 1485,1494 **** --- 1645,1668 ---- } return contextClassLoader; } /** + * TBD + */ + Continuation getContinuation() { + return cont; + } + + /** + * TBD + */ + void setContinuation(Continuation cont) { + this.cont = cont; + } + + /** * Sets the context ClassLoader for this Thread. The context * ClassLoader can be set when a thread is created, and allows * the creator of the thread to provide the appropriate class loader, * through {@code getContextClassLoader}, to code running in the thread * when loading classes and resources.
*** 1966,1975 **** --- 2140,2150 ---- } /** * Set the handler invoked when this thread abruptly terminates * due to an uncaught exception. + * * <p>A thread can take full control of how it responds to uncaught * exceptions by having its uncaught exception handler explicitly set. * If no such handler is set then the thread's {@code ThreadGroup} * object acts as its handler. * @param eh the object to use as this thread's uncaught exception
*** 1985,1997 **** uncaughtExceptionHandler = eh; } /** * Dispatch an uncaught exception to the handler. This method is ! * intended to be called only by the JVM. */ ! private void dispatchUncaughtException(Throwable e) { getUncaughtExceptionHandler().uncaughtException(this, e); } /** * Removes from the specified map any keys that have been enqueued --- 2160,2173 ---- uncaughtExceptionHandler = eh; } /** * Dispatch an uncaught exception to the handler. This method is ! * called by the VM when a thread terminates with an exception. It is also ! * called when a fiber terminates with an exception. */ ! void dispatchUncaughtException(Throwable e) { getUncaughtExceptionHandler().uncaughtException(this, e); } /** * Removes from the specified map any keys that have been enqueued
< prev index next >