diff -r 1181f58f30e2 -r b25362cec8ce src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java --- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java Wed Oct 02 08:27:17 2019 +0200 +++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java Wed Oct 02 09:16:18 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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,12 +26,14 @@ package java.nio.channels.spi; import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.HashSet; import java.util.Set; import sun.nio.ch.Interruptible; -import java.util.concurrent.atomic.AtomicBoolean; +import sun.nio.ch.SelectorImpl; /** @@ -69,12 +71,23 @@ public abstract class AbstractSelector extends Selector { - - private final AtomicBoolean selectorOpen = new AtomicBoolean(true); + private static final VarHandle CLOSED; + static { + try { + MethodHandles.Lookup l = MethodHandles.lookup(); + CLOSED = l.findVarHandle(AbstractSelector.class, "closed", boolean.class); + } catch (Exception e) { + throw new InternalError(e); + } + } + private volatile boolean closed; // The provider that created this selector private final SelectorProvider provider; + // cancelled-key, not used by the JDK Selector implementations + private final Set cancelledKeys; + /** * Initializes a new instance of this class. * @@ -83,10 +96,14 @@ */ protected AbstractSelector(SelectorProvider provider) { this.provider = provider; + if (this instanceof SelectorImpl) { + // not used in JDK Selector implementations + this.cancelledKeys = Set.of(); + } else { + this.cancelledKeys = new HashSet<>(); + } } - private final Set cancelledKeys = new HashSet(); - void cancel(SelectionKey k) { // package-private synchronized (cancelledKeys) { cancelledKeys.add(k); @@ -105,10 +122,10 @@ * If an I/O error occurs */ public final void close() throws IOException { - boolean open = selectorOpen.getAndSet(false); - if (!open) - return; - implCloseSelector(); + boolean changed = (boolean) CLOSED.compareAndSet(this, false, true); + if (changed) { + implCloseSelector(); + } } /** @@ -130,7 +147,7 @@ protected abstract void implCloseSelector() throws IOException; public final boolean isOpen() { - return selectorOpen.get(); + return !closed; } /**