以下代码来自java.lang.System.console()
方法:
private static volatile Console cons = null;
/**
* Returns the unique {@link java.io.Console Console} object associated
* with the current Java virtual machine, if any.
*
* @return The system console, if any, otherwise <tt>null</tt>.
*
* @since 1.6
*/
public static Console console() {
if (cons == null) {
synchronized (System.class) {
cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
}
}
return cons;
}
在我看来,这些是此方法中的错误。 我们应该这样写:
public static Console console() {
if (cons == null) {
synchronized (System.class) {
if (cons == null)
cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
}
}
return cons;
}
我说的对吗?你怎么看?
最佳答案
事实并非如此。您可以为其分配一个值,并且它已经被初始化。我认为 null 检查是多余的,它已经在外部被检查为 Tagir Valeev suggested ,在控制台的 JavaIoAccess 实现中。
您可能正在考虑线程争用,因为初始化发生在同步块(synchronized block)内,多个线程同时访问它会触发冗余的重新初始化。
所以你可以说它更像是一种减少开销的改进,而不是一个错误。
但是您应该阅读更多关于 Double checked locking 的内容,它完全包含您的场景。详情如下
有趣的是看到在 J2SE 1.4(及更早版本)中使用各种编译器的微妙问题。
在 J2SE 5.0 之后这些问题已经被修复
The volatile keyword now ensures that multiple threads handle the singleton instance correctly.
您会注意到控制台静态对象是易变的。
通过使用上面链接中描述的实现:
private static volatile Console cons = null;
public static Console console() {
Console result = console;
if (result == null) {
synchronized (System.class) {
result = console;
if (result == null) {
console = result =sun.misc.SharedSecrets.getJavaIOAccess().console();
}
}
}
return result;
}
你可以获得这样的性能提升:
Note the local variable result, which seems unnecessary. This ensures that in cases where console is already initialized (i.e., most of the time), the volatile field is only accessed once (due to "return result;" instead of "return console;"), which can improve the method's overall performance by as much as 25 percent - note: replaced helper with console for clarity
但我不确定第一次从多线程调用 console() 的频率 - 之后,由于外部空检查,初始化不再是问题。
此解决方案还会产生开销,因此实际性能提升值得商榷。因此,您的建议(如上所采纳)最多只能被视为一种改进。
关于java - System.console() 中可能的 JDK 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30117938/