Skip to content

Commit

Permalink
Draft: StringReader is implemented as Reader.of(String).withSynchroni…
Browse files Browse the repository at this point in the history
…zation
  • Loading branch information
mkarg committed Nov 10, 2024
1 parent 0e3fc93 commit aeb871a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 25 deletions.
99 changes: 99 additions & 0 deletions src/java.base/share/classes/java/io/Reader.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,105 @@ public void close() {
};
}

/**
* Returns a variant of this {@code Reader} that is safe for concurrent use
* by multiple threads.
*
* @implNote The default implementation locks a {@code ReentrantLock} before
* each method invocation, and unlocks it afterwards. Sublasses are
* encouraged to provide an optimized implementation.
*
* @return a variant of this {@code Reader} which is safe for concurrent use
* by multiple threads.
*
* @since 24
*/
public Reader withSynchronization() {
final Lock lock = new ReentrantLock();

return new Reader() {
@Override
public int read() throws IOException {
lock.lock();
try {
return Reader.this.read();
} finally {
lock.unlock();
}
}

@Override
public int read(char[] cbuf, int off, int len) throws IOException {
lock.lock();
try {
return Reader.this.read(cbuf, off, len);
} finally {
lock.unlock();
}
}

@Override
public long skip(long n) throws IOException {
lock.lock();
try {
return Reader.this.skip(n);
} finally {
lock.unlock();
}
}

@Override
public boolean ready() throws IOException {
lock.lock();
try {
return Reader.this.ready();
} finally {
lock.unlock();
}
}

@Override
public boolean markSupported() {
lock.lock();
try {
return Reader.this.markSupported();
} finally {
lock.unlock();
}
}

@Override
public void mark(int readAheadLimit) throws IOException {
lock.lock();
try {
return Reader.this.mark();
} finally {
lock.unlock();
}
}

@Override
public void reset() throws IOException {
lock.lock();
try {
return Reader.this.reset();
} finally {
lock.unlock();
}
}

@Override
public void close() {
lock.lock();
try {
return Reader.this.close();
} finally {
lock.unlock();
}
}
};
}

/**
* The object used to synchronize operations on this stream. For
* efficiency, a character-stream object may use an object other than
Expand Down
36 changes: 11 additions & 25 deletions src/java.base/share/classes/java/io/StringReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class StringReader extends Reader {
* @param s String providing the character stream.
*/
public StringReader(String s) {
r = Reader.of(s);
r = Reader.of(s).withSynchronization();
}

/**
Expand All @@ -60,9 +60,7 @@ public StringReader(String s) {
* @throws IOException If an I/O error occurs
*/
public int read() throws IOException {
synchronized (lock) {
return r.read();
}
return r.read();
}

/**
Expand All @@ -84,9 +82,7 @@ public int read() throws IOException {
* @throws IOException {@inheritDoc}
*/
public int read(char[] cbuf, int off, int len) throws IOException {
synchronized (lock) {
return r.read(cbuf, off, len);
}
return r.read(cbuf, off, len);
}

/**
Expand All @@ -110,9 +106,7 @@ public int read(char[] cbuf, int off, int len) throws IOException {
* @throws IOException {@inheritDoc}
*/
public long skip(long n) throws IOException {
synchronized (lock) {
return r.skip(n);
}
return r.skip(n);
}

/**
Expand All @@ -123,9 +117,7 @@ public long skip(long n) throws IOException {
* @throws IOException If the stream is closed
*/
public boolean ready() throws IOException {
synchronized (lock) {
return r.ready();
}
return r.ready();
}

/**
Expand All @@ -149,9 +141,7 @@ public boolean markSupported() {
* @throws IOException If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
synchronized (lock) {
r.mark(readAheadLimit);
}
r.mark(readAheadLimit);
}

/**
Expand All @@ -161,9 +151,7 @@ public void mark(int readAheadLimit) throws IOException {
* @throws IOException If an I/O error occurs
*/
public void reset() throws IOException {
synchronized (lock) {
r.reset();
}
r.reset();
}

/**
Expand All @@ -174,12 +162,10 @@ public void reset() throws IOException {
* while there is another thread blocking on the reader.
*/
public void close() {
synchronized (lock) {
try {
r.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
r.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

0 comments on commit aeb871a

Please sign in to comment.