I have been looking at the changes to FilterInputStream and
BufferedInputStream in 5.0, where the "in" field in FilterInputStream
has been changed to a volatile field since new code in BufferedInputStream
wanted it to be volatile. I am not quite sure what the code in
BufferedInputStream that checks for nullness of the "in" field is trying
to guard against, or why the "in" field needs to be volatile.
No matter if the field is volatile or not, there is always the possibility
that a thread gets hold of the "in" stream (in != null), and another thread
calls close() on that stream before the first thread has the oportunity to
operate on the stream. So, why is it so important that threads see the
clearing of the "in" field as soon as possible? Won't all actions on the
"in" stream throw the correct exception if it has been closed?
The volatile field change in FilterInputStream makes streams that do many
small reads perform much slower on SMP machines. This is an issue
especially when these streams operate on buffered streams since the I/O
costs are reduced and the slow down with regard to memory barriers becomes
dominant. Even more so, since both the read of the "in" field in the
buffered stream and the enclosing stream are volatile.
As an example, the _213_javac benchmark goes from 5.5 to 4.9 seconds on
an SMP machine when this volatile is removed. This seems a significant
difference.
See Comments section for further details.
BufferedInputStream in 5.0, where the "in" field in FilterInputStream
has been changed to a volatile field since new code in BufferedInputStream
wanted it to be volatile. I am not quite sure what the code in
BufferedInputStream that checks for nullness of the "in" field is trying
to guard against, or why the "in" field needs to be volatile.
No matter if the field is volatile or not, there is always the possibility
that a thread gets hold of the "in" stream (in != null), and another thread
calls close() on that stream before the first thread has the oportunity to
operate on the stream. So, why is it so important that threads see the
clearing of the "in" field as soon as possible? Won't all actions on the
"in" stream throw the correct exception if it has been closed?
The volatile field change in FilterInputStream makes streams that do many
small reads perform much slower on SMP machines. This is an issue
especially when these streams operate on buffered streams since the I/O
costs are reduced and the slow down with regard to memory barriers becomes
dominant. Even more so, since both the read of the "in" field in the
buffered stream and the enclosing stream are volatile.
As an example, the _213_javac benchmark goes from 5.5 to 4.9 seconds on
an SMP machine when this volatile is removed. This seems a significant
difference.
See Comments section for further details.
- relates to
-
JDK-4728096 java.io.BufferedInputStream has no synchronization on close operation
- Resolved
-
JDK-4956099 NullPointerException thrown from BufferedInputStream reading thread
- Resolved
-
JDK-8292698 Improve performance of DataInputStream
- Resolved