java - System.console() 中可能的 JDK 错误

标签 java

以下代码来自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/

相关文章:

java - 标准 Maven 目录布局中的外部文件目录

java - JNI 无法识别 jni 原始类型,例如字符串

Java Mysql更新语句

Java - 等待某种类型的按键继续

java - 如何使用 Java 从网站获取和提取数字?

java - ISSUE : java.net.InetAddress RESULTS 与 MYSQL 结果相比是错误的

java - 当查询存储为外部文件时,如何在 Spring boot 存储库中填充 native 查询的 @Query 值

javascript - 从java调用包含 'const'的javascript?

java - 公共(public)静态变量和私有(private)静态变量之间的区别

java - 为什么 compareTo 在应该为 false 时返回 true?