多线程实现原理

依然范特西╮ 提交于 2019-12-02 19:55:29

JMM保证原子性、可见性、有序性

原子性

两个高级的字节码指令monitorenter和monitorexit,在java中对应的Synchronized来保证代码块内的操作是原子的

可见性

  • volatile

    写操作的时候会多出一个lock前缀的汇编指令

    MESI的缓存一致性协议,来保证多CPU下的各个高速缓存中的数据的
    一致性

  • synchronized和final也可以实现可见性

有序性

  • volatile(禁止指令重排)

    遵循as-if-serial语义

  • synchronized(同一时刻只允许一条线程操作)

内存屏障

通过下面三种方式的作用:

  • 防止指令之间的重排序
  • 保证数据的可见性
  • 写屏障(store barrier)
    • storestore barrier
    • 强制所有在storestore内存屏障之前的所有执行,都要在该内存屏障之前执行,并发送缓存失效的信号

  • 读屏障(load barrier)
    • loadload barrier
    • 强制所有在load barrier读屏障之后的load指令,都在loadbarrier屏障之后执行

  • 全屏障(Full Barrier)
    • 相当于storeload,是一个全能型的屏障
    • 强制了所有在storeload barrier之前的store/load指令,都在该屏障之前被执行,所有在该屏障之后的的store/load指令,都在该屏障之后被执行
    • 禁止对storeload屏障前后的指令进行重排序

volatile为什么不能保证原子性

通过javap -c Demo.class,去查看字节码

对一个原子递增的操作,会分为三个步骤:

1.读取volatile变量的值到local;

2.增加变量的值;

3.把local的值写回让其他线程可见。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!