Skip to content

Commit 3d83706

Browse files
committed
more consistent interrupt state restoration
1 parent 90e6843 commit 3d83706

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ public static void sleepQuietly(final Duration duration) {
519519
try {
520520
sleep(duration);
521521
} catch (final InterruptedException ignore) {
522-
// Ignore & be quiet.
522+
// Restore interrupted state, ignore & be quiet.
523+
Thread.currentThread().interrupt();
523524
}
524525
}
525526

src/main/java/org/apache/commons/lang3/concurrent/BackgroundInitializer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,11 @@ public synchronized boolean isInitialized() {
345345
try {
346346
future.get();
347347
return true;
348-
} catch (CancellationException | ExecutionException | InterruptedException e) {
348+
} catch (CancellationException | ExecutionException e) {
349+
return false;
350+
} catch (InterruptedException e) {
351+
// reset interrupted state
352+
Thread.currentThread().interrupt();
349353
return false;
350354
}
351355
}

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
import java.util.List;
3737
import java.util.Objects;
3838
import java.util.concurrent.CountDownLatch;
39+
import java.util.concurrent.TimeUnit;
40+
import java.util.concurrent.atomic.AtomicBoolean;
41+
import java.util.concurrent.atomic.AtomicReference;
3942
import java.util.function.Predicate;
4043

4144
import org.apache.commons.lang3.ThreadUtils.ThreadGroupPredicate;
@@ -421,4 +424,26 @@ void testThreadsSameName() throws InterruptedException {
421424
}
422425
}
423426

427+
428+
@Test
429+
void sleepQuietly() throws Exception {
430+
CountDownLatch started = new CountDownLatch(1);
431+
AtomicBoolean interruptedAfter = new AtomicBoolean(false);
432+
AtomicReference<Throwable> thrown = new AtomicReference<>();
433+
Thread worker = new Thread(() -> {
434+
started.countDown();
435+
try {
436+
ThreadUtils.sleepQuietly(Duration.ofDays(1)); // should be cut short by interrupt
437+
interruptedAfter.set(Thread.currentThread().isInterrupted());
438+
} catch (Throwable t) {
439+
thrown.set(t);
440+
}
441+
});
442+
worker.start();
443+
assertTrue(started.await(2, TimeUnit.SECONDS), "Worker did not start in time");
444+
worker.interrupt();
445+
worker.join();
446+
assertNull(thrown.get());
447+
assertTrue(interruptedAfter.get());
448+
}
424449
}

0 commit comments

Comments
 (0)