src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java
changeset 58439 b25362cec8ce
parent 47216 71c04702a3d5
--- 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<SelectionKey> 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<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
-
     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;
     }
 
     /**