Ell*_*tus 67 java multithreading synchronization printstream
如果多个线程在没有同步的情况下调用System.out.println(String),输出是否可以交错?或者每行写入原子?该API只字不提同步的,所以这似乎是可能的,或者是由缓冲和/或虚拟机存储器模型等防止交织输出?
编辑:
例如,如果每个线程包含:
System.out.println("ABC");
Run Code Online (Sandbox Code Playgroud)
输出保证是:
ABC
ABC
Run Code Online (Sandbox Code Playgroud)
或者它可能是:
AABC
BC
Run Code Online (Sandbox Code Playgroud)
mae*_*ics 58
由于API文档,使上没有提及线程安全的System.out对象也不该PrintStream#println(String)方法 不能认为它是线程安全的.
但是,特定JVM的底层实现完全有可能使用该println方法的线程安全函数(例如,printf在glibc上),因此实际上,每个第一个示例都会保证输出(总是ABC\n那么ABC\n,从不散布的字符)按照你的第二个例子).但请记住,有许多JVM实现,并且只需遵守JVM规范,而不是该规范之外的任何约定.
如果您绝对必须确保没有println调用会在您描述时散布,那么您必须手动强制执行互斥,例如:
public void safePrintln(String s) {
synchronized (System.out) {
System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这个例子只是一个例子,不应被视为"解决方案"; 还有许多其他因素需要考虑.例如,safePrintln(...)如果所有代码都使用该方法并且没有System.out.println(...)直接调用,则上述方法是安全的.
twi*_*imo 20
OpenJDK源代码回答了您的问题:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
Run Code Online (Sandbox Code Playgroud)
参考:http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/39e8fe7a0af1/src/share/classes/java/io/PrintStream.java
Joh*_*int 10
只要您不更改OutputStream通道,System.setOut它就是线程安全的.
虽然它是线程安全的,你可以有很多线程写入System.out,使得
Thread-1
System.out.println("A");
System.out.println("B");
System.out.println("C");
Thread-2
System.out.println("1");
System.out.println("2");
System.out.println("3");
Run Code Online (Sandbox Code Playgroud)
可以阅读
1
2
A
3
B
C
Run Code Online (Sandbox Code Playgroud)
其他组合.
所以回答你的问题:
当您写入时System.out- 它获取OutputStream实例上的锁定- 然后它将写入缓冲区并立即刷新.
一旦它释放锁定,OutputStream就会刷新并写入.没有一个实例,你会有不同的字符串加入像1A 2B.
编辑以回答您的修改:
这不会发生System.out.println.由于PrintStream同步整个函数,它将填充缓冲区,然后以原子方式对其进行刷新.任何进入的新线程现在都有一个新的缓冲区可供使用.
| 归档时间: |
|
| 查看次数: |
33763 次 |
| 最近记录: |