Skip to content

Commit e1ffb6e

Browse files
committed
ThreadUtils.sleepQuietly(Duration) now restores the current thread's
interrupt flag when catching InterruptedException.
1 parent 2cdac97 commit e1ffb6e

3 files changed

Lines changed: 37 additions & 3 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ The <action> type attribute can be add,update,fix,remove.
113113
<action issue="LANG-1816" type="fix" dev="ggregory" due-to="Ivan Ponomarev, Gary Gregory">ArrayUtils contains/indexOf/indexesOf with tolerance fail to match NaN values #1589.</action>
114114
<action type="fix" dev="ggregory" due-to="Ivan Ponomarev, Gary Gregory">Fix StringIndexOutOfBoundsException message in StrBuilder.append(char[], int, int).</action>
115115
<action issue="LANG-1818" type="fix" dev="ggregory" due-to="Ivan Ponomarev, Gary Gregory">Fix ClassUtils.getShortClassName(Class) to correctly handle $ in valid class names #1591.</action>
116+
<action type="fix" dev="ggregory" due-to="Ivan Ponomarev, Gary Gregory">ThreadUtils.sleepQuietly(Duration) now restores the current thread's interrupt flag when catching InterruptedException.</action>
116117
<!-- ADD -->
117118
<action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_27.</action>
118119
<action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_JAVA_27.</action>

src/main/java/org/apache/commons/lang3/ThreadUtils.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,19 +507,21 @@ public static void sleep(final Duration duration) throws InterruptedException {
507507
}
508508

509509
/**
510-
* Sleeps for the given duration while ignoring {@link InterruptedException}.
510+
* Sleeps for the given duration without throwing {@link InterruptedException}.
511511
* <p>
512-
* The sleep duration may be shorter than duration if we catch a {@link InterruptedException}.
512+
* The sleep duration may be shorter than the given duration if we catch a {@link InterruptedException}.
513513
* </p>
514514
*
515515
* @param duration the length of time to sleep.
516+
* @see #sleep(Duration)
517+
* @see Thread#interrupted()
516518
* @since 3.13.0
517519
*/
518520
public static void sleepQuietly(final Duration duration) {
519521
try {
520522
sleep(duration);
521523
} catch (final InterruptedException ignore) {
522-
// Ignore & be quiet.
524+
Thread.currentThread().interrupt();
523525
}
524526
}
525527

src/test/java/org/apache/commons/lang3/ThreadUtilsTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.List;
3737
import java.util.Objects;
3838
import java.util.concurrent.CountDownLatch;
39+
import java.util.concurrent.atomic.AtomicBoolean;
3940
import java.util.function.Predicate;
4041

4142
import org.apache.commons.lang3.ThreadUtils.ThreadGroupPredicate;
@@ -245,6 +246,36 @@ void testSleepDuration() throws InterruptedException {
245246
ThreadUtils.sleep(Duration.ofMillis(1));
246247
}
247248

249+
@Test
250+
void testSleepQuietlyInterruptDuringSleep() throws Exception {
251+
final AtomicBoolean isInterrupted = new AtomicBoolean();
252+
final Thread testThread = new Thread(() -> {
253+
// This will be interrupted while sleeping
254+
ThreadUtils.sleepQuietly(Duration.ofSeconds(10));
255+
isInterrupted.set(Thread.currentThread().isInterrupted());
256+
});
257+
testThread.start();
258+
Thread.sleep(100);
259+
testThread.interrupt();
260+
testThread.join(1000);
261+
assertTrue(isInterrupted.get(), "Interrupted flag should be preserved after InterruptedException");
262+
}
263+
264+
@Test
265+
void testSleepQuietlyInterruptedFlagPreserved() {
266+
Thread.currentThread().interrupt();
267+
// Immediately throw InterruptedException and restores the interrupted status
268+
ThreadUtils.sleepQuietly(Duration.ofMillis(1000));
269+
assertTrue(Thread.interrupted(), "Interrupted flag should be preserved");
270+
}
271+
272+
@Test
273+
void testSleepQuietlyNormalNoInterrupt() {
274+
Thread.interrupted();
275+
ThreadUtils.sleepQuietly(Duration.ofMillis(10));
276+
assertFalse(Thread.currentThread().isInterrupted(), "Interrupted flag should not be set for normal sleep");
277+
}
278+
248279
@Test
249280
void testSystemThreadGroupExists() {
250281
final ThreadGroup systemThreadGroup = ThreadUtils.getSystemThreadGroup();

0 commit comments

Comments
 (0)