zoukankan      html  css  js  c++  java
  • JDK中的并发bug?

    最近研究Java并发,无意中在JDK8的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;
         }

    第一感觉,这个不是很像著名的双重检查加锁吗?再仔细一看,似乎有bug,似乎应该这样写的:

         public static Console console() {
             if (cons == null) {
                 synchronized (System.class) {
                      if (cons == null)
                            cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
                 }
             }
             return cons;
         }

    这个才是正确的 双重检查加锁 的正确写法。

    那么JDK中的写法似乎是有问题的:

    假如a,b两个线程执行到 if (cons == null) {  之后,然后a线程进入锁,获得了一个 cons对象,出锁,然后b线程在进入锁,又获得了一个不同的 cons对象,这样的话就和注释中的:Returns the unique {@link java.io.Console Console} object associated
         * with the current Java virtual machine, if any.

    矛盾了。

    另外如果sun.misc.SharedSecrets.getJavaIOAccess().console();每次返回都是相同的 对象,那就没有必要使用synchronized (System.class) 锁了。

    但是一想,如果JDK发生这样低级的bug,又感觉不太可能吧,但是自己从代码上看又确实有bug,请知道其中原委高手指点......

  • 相关阅读:
    Angular5的new feature
    Angular集成UEditor
    Angular集成admin-lte框架
    Angular TypeScript开发环境集成jQuery扩展插件
    如何在 Docker 容器中运行 Kali Linux 2.0
    信息系统安全等级保护基本要求
    Angular学习笔记
    Ubuntu16.04部署phantomjs的一个问题
    仿探探卡片滑动vue封装并发布到npm
    使用vscode,新建.vue文件,tab自动生成vue代码模板
  • 原文地址:https://www.cnblogs.com/digdeep/p/4487304.html
Copyright © 2011-2022 走看看