< prev index next >
src/java.base/share/classes/java/io/PrintStream.java
Print this page
rev 53030 : 8215412: Optimize PrintStream.println methods
Reviewed-by: core-libs
@@ -63,10 +63,11 @@
public class PrintStream extends FilterOutputStream
implements Appendable, Closeable
{
private final boolean autoFlush;
+ private final boolean internal;
private boolean trouble = false;
private Formatter formatter;
/**
* Track both the text- and character-output streams, so that their buffers
@@ -105,14 +106,19 @@
/* Private constructors */
private PrintStream(boolean autoFlush, OutputStream out) {
super(out);
this.autoFlush = autoFlush;
+ this.internal = isInternal();
this.charOut = new OutputStreamWriter(this);
this.textOut = new BufferedWriter(charOut);
}
+ private final boolean isInternal() {
+ return this.getClass().getModule() == PrintStream.class.getModule();
+ }
+
/* Variant of the private constructor so that the given charset name
* can be verified before evaluating the OutputStream argument. Used
* by constructors creating a FileOutputStream that also take a
* charset name.
*/
@@ -189,10 +195,11 @@
* @since 10
*/
public PrintStream(OutputStream out, boolean autoFlush, Charset charset) {
super(out);
this.autoFlush = autoFlush;
+ this.internal = isInternal();
this.charOut = new OutputStreamWriter(this, charset);
this.textOut = new BufferedWriter(charOut);
}
/**
@@ -573,11 +580,11 @@
* The following private methods on the text- and character-output streams
* always flush the stream buffers, so that writes to the underlying byte
* stream occur as promptly as with the original PrintStream.
*/
- private void write(char buf[]) {
+ private void write(char[] buf) {
try {
synchronized (this) {
ensureOpen();
textOut.write(buf);
textOut.flushBuffer();
@@ -586,10 +593,28 @@
for (int i = 0; i < buf.length; i++)
if (buf[i] == '\n')
out.flush();
}
}
+ } catch (InterruptedIOException x) {
+ Thread.currentThread().interrupt();
+ } catch (IOException x) {
+ trouble = true;
+ }
+ }
+
+ private void writeln(char[] buf) {
+ try {
+ synchronized (this) {
+ ensureOpen();
+ textOut.write(buf);
+ textOut.newLine();
+ textOut.flushBuffer();
+ charOut.flushBuffer();
+ if (autoFlush)
+ out.flush();
+ }
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
@@ -614,10 +639,30 @@
catch (IOException x) {
trouble = true;
}
}
+ private void writeln(String s) {
+ try {
+ synchronized (this) {
+ ensureOpen();
+ textOut.write(s);
+ textOut.newLine();
+ textOut.flushBuffer();
+ charOut.flushBuffer();
+ if (autoFlush)
+ out.flush();
+ }
+ }
+ catch (InterruptedIOException x) {
+ Thread.currentThread().interrupt();
+ }
+ catch (IOException x) {
+ trouble = true;
+ }
+ }
+
private void newLine() {
try {
synchronized (this) {
ensureOpen();
textOut.newLine();
@@ -778,113 +823,145 @@
* {@link #println()}.
*
* @param x The {@code boolean} to be printed
*/
public void println(boolean x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints a character and then terminate the line. This method behaves as
* though it invokes {@link #print(char)} and then
* {@link #println()}.
*
* @param x The {@code char} to be printed.
*/
public void println(char x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints an integer and then terminate the line. This method behaves as
* though it invokes {@link #print(int)} and then
* {@link #println()}.
*
* @param x The {@code int} to be printed.
*/
public void println(int x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints a long and then terminate the line. This method behaves as
* though it invokes {@link #print(long)} and then
* {@link #println()}.
*
* @param x a The {@code long} to be printed.
*/
public void println(long x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints a float and then terminate the line. This method behaves as
* though it invokes {@link #print(float)} and then
* {@link #println()}.
*
* @param x The {@code float} to be printed.
*/
public void println(float x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints a double and then terminate the line. This method behaves as
* though it invokes {@link #print(double)} and then
* {@link #println()}.
*
* @param x The {@code double} to be printed.
*/
public void println(double x) {
+ if (internal) {
+ writeln(String.valueOf(x));
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints an array of characters and then terminate the line. This method
* behaves as though it invokes {@link #print(char[])} and
* then {@link #println()}.
*
* @param x an array of chars to print.
*/
- public void println(char x[]) {
+ public void println(char[] x) {
+ if (internal) {
+ writeln(x);
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints a String and then terminate the line. This method behaves as
* though it invokes {@link #print(String)} and then
* {@link #println()}.
*
* @param x The {@code String} to be printed.
*/
public void println(String x) {
+ if (internal) {
+ writeln(x);
+ } else {
synchronized (this) {
print(x);
newLine();
}
}
+ }
/**
* Prints an Object and then terminate the line. This method calls
* at first String.valueOf(x) to get the printed object's string value,
* then behaves as
@@ -893,15 +970,21 @@
*
* @param x The {@code Object} to be printed.
*/
public void println(Object x) {
String s = String.valueOf(x);
+ if (internal) {
+ // need to do String.valueOf(s) since String.valueOf(x)
+ // might return null
+ writeln(String.valueOf(s));
+ } else {
synchronized (this) {
print(s);
newLine();
}
}
+ }
/**
* A convenience method to write a formatted string to this output stream
* using the specified format string and arguments.
< prev index next >