• clz1341521 置顶
    2018-08-10
    杨老师,请教一个问题,望答复。
    volatile boolean和atomicboolean 一样是原子性的吗?

    作者回复: volatile只保证可见性

     2
     12
  • 公号-云原生程序员
    2018-07-12
    可从四个维度去理解JMM

        1    从JVM运行时视角来看,JVM内存可分为JVM栈、本地方法栈、PC计数器、方法区、堆;其中前三区是线程所私有的,后两者则是所有线程共有的

        2    从JVM内存功能视角来看,JVM可分为堆内存、非堆内存与其他。其中堆内存对应于上述的堆区;非堆内存对应于上述的JVM栈、本地方法栈、PC计数器、方法区;其他则对应于直接内存

        3    从线程运行视角来看,JVM可分为主内存与线程工作内存。Java内存模型规定了所有的变量都存储在主内存中;每个线程的工作内存保存了被该线程使用到的变量,这些变量是主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量

        4    从垃圾回收视角来看,JVM中的堆区=新生代+老年代。新生代主要用于存放新创建的对象与存活时长小的对象,新生代=E+S1+S2;老年代则用于存放存活时间长的对象
    展开
     1
     69
  • - -
    2018-07-19
    个人觉得happens-before原则最难理解的就是和时间次序上的关系,就比如volatile变量的写操作happens-before其后的读操作,之前很难理解“其后”的含义,一直认为既然是先发生的操作,结果肯定对后续的操作可见啊,以至于认为这个原则是不是多余的。结合了jmm内存模型来看的话就很好理解了,一个操作完成,其结果只是在线程内可见的,在结果写回主存并被其他线程读取前,即使其他线程操作靠后,也无法看见其操作结果。所以才会有volatile、锁等一系列可见性原则的约束
    
     22
  • 三木子
    2018-07-12
    刚看完文章,在看了下《深入JAVA虚拟机》的java内存模型章节,又加深点印象。这本书真不能像小说一样读!
    
     10
  • Ab
    2018-07-18
    jmm可以从两个方面理解,一是抽象内存结构,jmm把内存结构抽象成主内存和线程本地内存两种,在计算时,从主内存中加载数据,在本地内存计算,然后在刷新到主内存,但这种模型有明显的一致性问题,二是jmm可以理解我一组保住内存可见性及成正确性的规范,因为这种模型存在明显的一致性问题,同时,由于java编译器指令重排序优化和cpu乱序执行优化的存在,使问题变得更加复杂,所以jmm基于内存屏障提供了类似sa if serial以及happens before的保障。从使用者的角度理解,jmm平衡了jvm工程师以及cpu工程师在性能上的需求和java程序员在简单性上的渴望,所以jmm在保证正确性的同时会最大限度的放宽对指令重排和乱序执行的限制。对于java程序员,jmm提供了如volatile和synchronized这样的顶层机制为程序员提供简单的编程模型。(参考老师的文章及java并发编程艺术 理解)
    展开
    
     8
  • Ab
    2018-07-18
    jmm可以从两个方面理解,第一个方面是jmm规范了一个抽象的内存结构,jmm运行时内存进行简化抽象得到了主内存和本地内存两块内存区域,在线程运行时,从主内存中加载数据到本地内存,在本地内存中完成计算后,在刷新到主内存。第二个方面是jmm可以理解我一组保证数据内存可见性和程序正确性的规则,由于这种内存模型存在很明显的数据一致性问题,再加上编译器的指令重排序和cpu乱序执行优化,使问题更加复杂了,而jmm就是通过类似内存屏障等手段保证了内存可见性问题以及在多线程环境下乱序优化和指令重排序带来的线程安全性问题。从使用者的角度理解,jmm实际上平衡了java程序员对简单性的渴望和jvm工程师cpu工程师对性能的追求的平衡,面向底层时,jmm在保证正确性的同时最大限度的放宽了对指令重排序和乱序执行优化的限制,面向上层jmm通过内存屏障实现了volatile和synchronized等内存语意,使程序员可以简单方便的应用这些特性来保证程序的程序的正确性。
    展开
    
     7
  • 风轨
    2018-08-14
    先看了两遍,始终处于懵逼的状态,后来去把《深入理解java虚拟机》相关部分仔细阅读一下,再回来看终于看懂了!
    
     3
  • 蠢蠢欲动的腹肌
    2018-08-14
    在网上看了下让双检锁生效的方法,除了用volatile修饰变量外,还有其他两种方式
    1、用final 修饰变量
    2、用本地线程的方式修复,即在创建对象时存取本地线程(final的),在get的时候再从本地取

    作者回复: 对,这里有各种tricky的技巧

    
     3
  • clz1341521
    2018-08-10
    1,验证出 “可见性问题”,这个很容复现
    2,验证出“cpu指令优化重排”导致的如 双检锁 中对象未初始化完毕,即被使用问题。这个对象构造要慢,才容易复现
    
     1
  • S
    2020-02-02
    杨老师,请教个问题:
    在说volatile可见性举的两个例子中,针对第一个,为什么在死循环中添加了一个System.out就会使死循环退出?这个System.out为啥会起到作用
    
    
  • 西兹兹
    2019-11-11
    老师讲了JSR133里的1个规则, volatile
    
    
  • ddddd🐳
    2019-10-31
    关于volatile的这句描述-“对于 volatile 变量,对它的写操作,保证 happen-before 在随后对该变量的读取操作。”,我始终不理解,写了很多demo测试,也没弄清楚,老师能给个简单的demo code吗?;
    
    
  • 随心而至
    2019-09-20
    配合深入理解Java虚拟机第12章食用,效果更佳
    
    
  • yzh
    2019-08-15
    老是,具体有什么工具可以验证JMM的所有执行可能
    
    
  • 浪尖
    2019-07-03
    读操作插入的屏障,不都是在volatile读之后吗?
     1
    
  • 谢涛
    2019-06-06
    茅塞顿开了,赞
    
    
  • 冰激凌的眼泪
    2019-03-03
    单线程内的happens before和优化后的有序性不冲突吗?这里的happens before是指的高级语言语句级还是cpu指令级呢?
     1
    
  • Pan
    2019-02-20
    杨老师,请教个问题,前面说到的volatile变量是在写操作之后,编译器插入一个写屏障,为什么不是在写操作之前,和我理解有点出入,望赐教。
    
    
  • Seven4X
    2018-08-02
    之前的问题找到解决方法了,就是使用concurrenthashmap的computeIfAbsent方法,这个方法是加锁的.
    文中提到的volatile的例子,我试了一下并没有复现出来,根据《深入理解JVM》这本书关于volatile的例子复现出来了,了解了volatile并不能保证字段线程安全
    然后Brian Goetz的《java theory and practice:managing volatility》仔细拜读了一下,还是没有找到能够百分百复现出来的办法
    请问有什么方法能够稳定复现出来文中的例子吗?
    展开
    
    
  • philip
    2018-07-20
    老师volatile变量的happens_befor中ues之前必须load。但是load了不中间不对变量进行操作,过一会再操作,但是其他线程已经操作了volitile变量。此时被加载到工作区的volatile变量再执行assgin操作时应该不会重新加载主存数据了对不?
    
    
我们在线,来聊聊吧