< prev index next >

src/java.base/share/classes/java/io/Reader.java

Print this page
@@ -23,14 +23,14 @@
   * questions.
   */
  
  package java.io;
  
- 
  import java.nio.CharBuffer;
  import java.nio.ReadOnlyBufferException;
  import java.util.Objects;
+ import jdk.internal.misc.InternalLock;
  
  /**
   * Abstract class for reading character streams.  The only methods that a
   * subclass must implement are read(char[], int, int) and close().  Most
   * subclasses, however, will override some of the methods defined here in order

@@ -152,24 +152,30 @@
      /**
       * Creates a new character-stream reader whose critical sections will
       * synchronize on the reader itself.
       */
      protected Reader() {
-         this.lock = this;
+         // use InternalLock for trusted classes
+         Class<?> clazz = getClass();
+         if (clazz == InputStreamReader.class
+             || clazz == BufferedReader.class
+             || clazz == FileReader.class
+             || clazz == sun.nio.cs.StreamDecoder.class) {
+             this.lock = new InternalLock();
+         } else {
+             this.lock = this;
+         }
      }
  
      /**
       * Creates a new character-stream reader whose critical sections will
       * synchronize on the given object.
       *
       * @param lock  The Object to synchronize on.
       */
      protected Reader(Object lock) {
-         if (lock == null) {
-             throw new NullPointerException();
-         }
-         this.lock = lock;
+         this.lock = Objects.requireNonNull(lock);
      }
  
      /**
       * Attempts to read characters into the specified character buffer.
       * The buffer is used as a repository of characters as-is: the only

@@ -295,23 +301,37 @@
       * @throws     IOException  If an I/O error occurs
       */
      public long skip(long n) throws IOException {
          if (n < 0L)
              throw new IllegalArgumentException("skip value is negative");
-         int nn = (int) Math.min(n, maxSkipBufferSize);
-         synchronized (lock) {
-             if ((skipBuffer == null) || (skipBuffer.length < nn))
-                 skipBuffer = new char[nn];
-             long r = n;
-             while (r > 0) {
-                 int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
-                 if (nc == -1)
-                     break;
-                 r -= nc;
+         Object lock = this.lock;
+         if (lock instanceof InternalLock locker) {
+             locker.lock();
+             try {
+                 return lockedSkip(n);
+             } finally {
+                 locker.unlock();
              }
-             return n - r;
+         } else {
+             synchronized (lock) {
+                 return lockedSkip(n);
+             }
+         }
+     }
+ 
+     private long lockedSkip(long n) throws IOException {
+         int nn = (int) Math.min(n, maxSkipBufferSize);
+         if ((skipBuffer == null) || (skipBuffer.length < nn))
+             skipBuffer = new char[nn];
+         long r = n;
+         while (r > 0) {
+             int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
+             if (nc == -1)
+                 break;
+             r -= nc;
          }
+         return n - r;
      }
  
      /**
       * Tells whether this stream is ready to be read.
       *
< prev index next >