diff --git a/src/java.base/share/classes/java/lang/InterruptedException.java b/src/java.base/share/classes/java/lang/InterruptedException.java index ef13e5f94e309..e8cf3d28bc590 100644 --- a/src/java.base/share/classes/java/lang/InterruptedException.java +++ b/src/java.base/share/classes/java/lang/InterruptedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,24 +26,19 @@ package java.lang; /** - * Thrown when a thread is waiting, sleeping, or otherwise occupied, - * and the thread is interrupted, either before or during the activity. - * Occasionally a method may wish to test whether the current - * thread has been interrupted, and if so, to immediately throw - * this exception. The following code can be used to achieve - * this effect: - * {@snippet lang=java : - * if (Thread.interrupted()) // Clears interrupted status! - * throw new InterruptedException(); - * } + * Thrown when a thread executing a blocking method is {@linkplain Thread#interrupt() + * interrupted}. {@link Thread#sleep(long) Thread.sleep}, {@link Object#wait() + * Object.wait} and many other blocking methods throw this exception if interrupted. + * + *

Blocking methods that throw {@code InterruptedException} clear the thread's + * interrupted status before throwing the exception. Code that catches {@code + * InterruptedException} should rethrow the exception, or restore the current thread's + * interrupted status, with {@link Thread#currentThread() + * Thread.currentThread()}.{@link Thread#interrupt() interrupt()}, before continuing + * normally or handling it by throwing another type of exception. * * @author Frank Yellin - * @see java.lang.Object#wait() - * @see java.lang.Object#wait(long) - * @see java.lang.Object#wait(long, int) - * @see java.lang.Thread#sleep(long) - * @see java.lang.Thread#interrupt() - * @see java.lang.Thread#interrupted() + * @see Thread##thread-interruption Thread Interruption * @since 1.0 */ public class InterruptedException extends Exception { diff --git a/src/java.base/share/classes/java/lang/Thread.java b/src/java.base/share/classes/java/lang/Thread.java index ace29f30a560f..798ded2b9410c 100644 --- a/src/java.base/share/classes/java/lang/Thread.java +++ b/src/java.base/share/classes/java/lang/Thread.java @@ -63,8 +63,9 @@ *

A thread terminates if either its {@code run} method completes normally, * or if its {@code run} method completes abruptly and the appropriate {@linkplain * Thread.UncaughtExceptionHandler uncaught exception handler} completes normally or - * abruptly. With no code left to run, the thread has completed execution. The - * {@link #join() join} method can be used to wait for a thread to terminate. + * abruptly. With no code left to run, the thread has completed execution. The {@link + * #isAlive isAlive} method can be used to test if a started thread has terminated. + * The {@link #join() join} method can be used to wait for a thread to terminate. * *

Threads have a unique {@linkplain #threadId() identifier} and a {@linkplain * #getName() name}. The identifier is generated when a {@code Thread} is created @@ -79,7 +80,7 @@ * {@code Thread} supports a special inheritable thread local for the thread * {@linkplain #getContextClassLoader() context-class-loader}. * - *

Platform threads

+ *

Platform Threads

*

{@code Thread} supports the creation of platform threads that are * typically mapped 1:1 to kernel threads scheduled by the operating system. * Platform threads will usually have a large stack and other resources that are @@ -99,7 +100,7 @@ * #getPriority() thread priority} and are members of a {@linkplain ThreadGroup * thread group}. * - *

Virtual threads

+ *

Virtual Threads

*

{@code Thread} also supports the creation of virtual threads. * Virtual threads are typically user-mode threads scheduled by the Java * runtime rather than the operating system. Virtual threads will typically require @@ -124,7 +125,7 @@ * Virtual threads have a fixed {@linkplain #getPriority() thread priority} * that cannot be changed. * - *

Creating and starting threads

+ *

Creating And Starting Threads

* *

{@code Thread} defines public constructors for creating platform threads and * the {@link #start() start} method to schedule threads to execute. {@code Thread} @@ -153,7 +154,7 @@ * ThreadFactory factory = Thread.ofVirtual().factory(); * } * - *

Inheritance when creating threads

+ *

Inheritance When Creating Threads

* A {@code Thread} created with one of the public constructors inherits the daemon * status and thread priority from the parent thread at the time that the child {@code * Thread} is created. The {@linkplain ThreadGroup thread group} is also inherited when @@ -171,7 +172,45 @@ * {@link Builder#inheritInheritableThreadLocals(boolean) inheritInheritableThreadLocals} * method can be used to select if the initial values are inherited. * - *

Unless otherwise specified, passing a {@code null} argument to a constructor + *

Thread Interruption

+ * A {@code Thread} has an interrupted status which serves as a "request" for + * code executing in the thread to "stop or cancel its current activity". The interrupted + * status is set by invoking the target thread's {@link #interrupt()} method. Many methods + * that cause a thread to block or wait are interruptible, meaning they detect + * that the thread's interrupted status is set and cause execution to return early from + * the method, usually by throwing an exception. + * + *

If a thread executing {@link #sleep(long) Thread.sleep} or {@link Object#wait() + * Object.wait} is interrupted then it causes the method to throw {@link InterruptedException}. + * Methods that throw {@code InterruptedException} do so after first clearing the + * interrupted status. Code that catches {@code InterruptedException} should rethrow the + * exception, or restore the current thread's interrupted status, with + * {@link #currentThread() Thread.currentThread()}.{@link #interrupt()}, before + * continuing normally or handling it by throwing another type of exception. Code that + * throws another type of exception with the {@code InterruptedException} as {@linkplain + * Throwable#getCause() cause}, or the {@code InterruptedException} as a {@linkplain + * Throwable#addSuppressed(Throwable) suppressed exception}, should also restore the + * interrupted status before throwing the exception. + * + *

If a thread executing a blocking I/O operation on an {@link + * java.nio.channels.InterruptibleChannel} is interrupted then it causes the channel to be + * closed, and the blocking I/O operation to throw {@link java.nio.channels.ClosedByInterruptException} + * with the thread's interrupted status set. If a thread blocked in a {@linkplain + * java.nio.channels.Selector selection operation} is interrupted then it causes the + * selection operation to return early, with the thread's interrupted status set. + * + *

Code that doesn't invoke any interruptible methods can still respond to interrupt + * by polling the current thread's interrupted status with + * {@link Thread#currentThread() Thread.currentThread()}.{@link #isInterrupted() + * isInterrupted()}. + * + *

In addition to the {@link #interrupt()} and {@link #isInterrupted()} methods, + * {@code Thread} also defines the static {@link #interrupted() Thread.interrupted()} + * method to test the current thread's interrupted status and clear it. It should be rare + * to need to use this method. + * + *

Null Handling

+ * 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 @@ -190,8 +229,9 @@ * * {@systemProperty jdk.virtualThreadScheduler.parallelism} * - * The number of platform threads available for scheduling virtual - * threads. It defaults to the number of available processors. + * The scheduler's target parallelism. This is the number of platform threads + * available for scheduling virtual threads. It defaults to the number of available + * processors. * * * @@ -202,6 +242,8 @@ * * * + *

The virtual thread scheduler can be monitored and managed with the + * {@code jdk.management.VirtualThreadSchedulerMXBean} management interface. * * @since 1.0 */ @@ -1558,6 +1600,9 @@ private void exit() { * @implNote In the JDK Reference Implementation, interruption of a thread * that is not alive still records that the interrupt request was made and * will report it via {@link #interrupted()} and {@link #isInterrupted()}. + * + * @see ##thread-interruption Thread Interruption + * @see #isInterrupted() */ public void interrupt() { // Setting the interrupted status must be done before reading nioBlocker. @@ -1587,8 +1632,19 @@ public void interrupt() { * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * + * @apiNote It should be rare to use this method directly. It is intended + * for cases that detect {@linkplain ##thread-interruption thread interruption} + * and clear the interrupted status before throwing {@link InterruptedException}. + * It may also be useful for cases that implement an uninterruptible + * method that makes use of an interruptible method such as + * {@link LockSupport#park()}. The {@code interrupted()} method can be used + * to test if interrupted and clear the interrupted status to allow the code + * retry the interruptible method. The uninterruptible method + * should restore the interrupted status before it completes. + * * @return {@code true} if the current thread has been interrupted; * {@code false} otherwise. + * @see ##thread-interruption Thread Interruption * @see #isInterrupted() */ public static boolean interrupted() { @@ -1601,7 +1657,8 @@ public static boolean interrupted() { * * @return {@code true} if this thread has been interrupted; * {@code false} otherwise. - * @see #interrupted() + * @see ##thread-interruption Thread Interruption + * @see #interrupt() */ public boolean isInterrupted() { return interrupted;