< prev index next >

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

Print this page
*** 23,14 ***
   * questions.
   */
  
  package java.io;
  
- 
  import java.nio.CharBuffer;
  import java.nio.ReadOnlyBufferException;
  import java.util.Objects;
  
  /**
   * 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
--- 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 ***
      /**
       * Creates a new character-stream reader whose critical sections will
       * synchronize on the reader itself.
       */
      protected Reader() {
!         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;
      }
  
      /**
       * Attempts to read characters into the specified character buffer.
       * The buffer is used as a repository of characters as-is: the only
--- 152,30 ---
      /**
       * Creates a new character-stream reader whose critical sections will
       * synchronize on the reader itself.
       */
      protected Reader() {
!         // 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) {
!         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 ***
       * @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;
              }
!             return n - r;
          }
      }
  
      /**
       * Tells whether this stream is ready to be read.
       *
--- 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");
!         Object lock = this.lock;
!         if (lock instanceof InternalLock locker) {
!             locker.lock();
!             try {
!                 return lockedSkip(n);
!             } finally {
!                 locker.unlock();
              }
!         } 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 >