java吧 关注:1,293,887贴子:12,828,907
  • 21回复贴,共1

技术贴,问个问题

只看楼主收藏回复

synchronized保证了同步块的原子性,这句话对不对?


1楼2019-02-28 00:16回复
    为啥这么问?


    来自iPhone客户端2楼2019-02-28 08:51
    收起回复
      2026-01-08 09:43:21
      广告
      不感兴趣
      开通SVIP免广告


      IP属地:浙江来自Android客户端3楼2019-02-28 08:56
      收起回复
        建议你先百度一下什么叫原子性,原子性是事务的特性,我觉得同步的特性应该是有序性


        IP属地:上海4楼2019-02-28 09:16
        收起回复
          仔细研究了一下,发现我理解的有问题,重新说一遍吧。
          应该是这样的:指令重排序,导致同步代码快还没执行完毕而instance != null(因为指向了内存地址,所以不为空,但是没初始化),那么线程二存在一定可能会返回上个线程的没有初始化的对象而导致错误的结果。


          IP属地:江西5楼2019-02-28 09:44
          收起回复
            我觉得说的没啥大问题


            IP属地:辽宁6楼2019-02-28 10:35
            回复
              觉得双重检测的有问题的是下边的过程
              if (instance == null ) { // step 1
              synchronice {
              if (instance == null) instance = new Object(); //step 2
              }
              }
              new Object()这个过程不是原子性操作,分了3个子步骤,初始化,赋值等(差不多吧),因为重排序的原因,导致赋值先执行,初始化还没完成。也就是执行step2的时候,instance已经不为空了,赋值操作发生了,初始化还在执行中。
              所以第二个线程执行到step1,这里还没进去锁,发现instance != null,就返回了,但是这时候线程1在做初始化工作,线程2拿到的是未完成初始化的对象。


              IP属地:广东7楼2019-02-28 11:51
              回复
                大部分人是这样解释的,双重检测为什么要加volatile。但是我测不出来,给构造方法加个Thread.sleep(),也没测出来有什么问题。
                按我的理解,内存划分主内存,和工作内存(线程独占),new发生在工作内存上,初始化完成之后,才会将静态变量的值写回主内存。不都说线程会持有静态变量的副本吗,那new操作时不应该赋值给副本吗,怎么会直接写回主内存了。
                不太懂这个,反正我现在无脑上静态内部类了。双重检测见鬼去吧


                IP属地:广东8楼2019-02-28 11:56
                收起回复
                  2026-01-08 09:37:21
                  广告
                  不感兴趣
                  开通SVIP免广告
                  我觉得差不多 除了执行wait()


                  IP属地:广东9楼2019-02-28 11:58
                  回复
                    synchronized,和@service的原子性有什么区别?


                    IP属地:浙江来自Android客户端10楼2019-02-28 16:34
                    回复
                      自学?


                      IP属地:湖南来自Android客户端11楼2019-02-28 21:59
                      回复