RFR: 8349543: LinkedBlockingDeque does not immediately throw InterrruptedException in put/take

kabutz duke at openjdk.org
Thu Feb 6 16:02:09 UTC 2025


On Wed, 5 Feb 2025 18:38:40 GMT, Doug Lea <dl at openjdk.org> wrote:

> Thanks for finding this. The only question is whether we believe that any existing usage might depend on current behavior, and if so should it be done anyway?

Good question - your call Doug.

LinkedBlockingDeque's comment is the same as LInkedBlockingQueue's (inherited from BlockingQueue): "@throws InterruptedException if interrupted while waiting" - however all the other classes that do throw this InterruptedException would do so on entry, even if we are not technically waiting.

Other examples where this behaviour is consistent is LinkedTransferQueue.take(), PriorityBlockingQueue.take(), etc.:


import java.util.concurrent.*;

public class InterruptionsIgnoredOnTakeOtherQueues {
    public static void main(String... args) throws InterruptedException {
        // Ensure that take() immediately throws an InterruptedException
        // if the thread is interrupted for other BlockingQueues
        try (var pool = Executors.newSingleThreadExecutor()) {
            var success = pool.submit(() -> {
                test(new LinkedTransferQueue<>());
                test(new PriorityBlockingQueue<>());
                test(new ArrayBlockingQueue<>(10));
                test(new LinkedBlockingQueue<>());
                return null;
            });
            try {
                success.get();
            } catch (ExecutionException e) {
                try {
                    throw e.getCause();
                } catch (Error | RuntimeException unchecked) {
                    throw unchecked;
                } catch (Throwable cause) {
                    throw new AssertionError(cause);
                }
            }
        }
    }

    private static void test(BlockingQueue<Integer> queue) {
        queue.add(42);
        Thread.currentThread().interrupt();
        try {
            queue.take();
            fail("Expected InterruptedException in " + queue.getClass().getSimpleName() + ".take()");
        } catch (InterruptedException expected) {
            // good that's what we want
        }
    }

    private static void fail(String message) {
        throw new AssertionError(message);
    }
}

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23464#issuecomment-2640235199


More information about the core-libs-dev mailing list