java并发 - 自底向上的原理分析
程序员文章站
2022-06-25 17:02:34
事先声明,我只是java并发的新手,这篇文章也只是我阅读《java并发编程的艺术》一书(内容主要涉及前3章)的一些总结和感悟。希望大家能多多讨论,对于错误的地方还请指出。 0. 简介 程序的世界是有层次分明的,每层都对外封装细节而提供一些方式或者说接口来提供功能,甚至是约束功能来换取正确性等等。那么 ......
事先声明,我只是java并发的新手,这篇文章也只是我阅读《java并发编程的艺术》一书(内容主要涉及前3章)的一些总结和感悟。希望大家能多多讨论,对于错误的地方还请指出。
0. 简介
程序的世界是有层次分明的,每层都对外封装细节而提供一些方式或者说接口来提供功能,甚至是约束功能来换取正确性等等。那么接下来,就用分层的思想作为灵魂,各种内存模型作为骨架,来简单讨论Java并发的原理。
1. 处理器内存模型
我们面对的第一个问题是,一个好的处理器要满足什么条件?就像考试的学生一样,当然是做得又快,对得又多。对于处理器来说一般要满足两个条件: 1. 效率 2. 正确性
1.1 效率
对于效率来说,处理器提供了很多的机制来满足这一点,并行,指令流水线,指令重排,缓存机制等等。但这些方式必须加以限制来保证正确性,或者说效率和正确性在一定程度上是相互制约的,我们必须加以权衡,合理折中。
1.2 正确性
那么怎么保证正确性呢?同样除了处理器的一些内部的机制,比如禁止某些指令重排,缓存一致性,总线锁,缓存锁定等等,同时还向其上层提供了好的方法,比如说内存屏障,CAS等等,这些方法、机制会让上层(通过合理的方式)更好的来保证程序的正确性,就像Java会提供volatile,synchronized等等方式来让程序员(通过合理的方式)调用保证程序的线程安全。 让我们更加深入这个话题,一个程序怎么样才叫正确?要满足什么性质?简单来说,有三条性质: 1. 原子性,就是要么全部做要么全不做,需要硬件的配合,比如CAS。 2. 可见性,由于缓存的存在,要让一个处理器处理的结果对其他处理器可见,首先要把缓存写入内存。 3. 顺序性,程序必须保持一定的顺序依次的产生结果。 注意,处理器的很多机制可以保持其中多种性质,比如内存屏障就可以把缓存刷新进入内存,而其他处理器的缓存无效来保证可见性,和通过禁止指令重排来保证顺序性。比如总线锁,缓存锁定,缓存一致性就通过各种方式来保证顺序性和原子性。
2. java内存模型
好了我们更上一层楼,我们刚刚说在下一层(处理器)提供了各种机制来保证效率和正确性,而这一层正是要使用这些机制来到达这一层,也就是JRE和编译器的正确性和效率。 JMM(即java内存模型)同处理器模型一样,也有很多的机制,包括各种优化。对外也提供volatile,synchronized和臭名昭著的concurrent包。上层的程序员也要使用(合理的方式)这些Java语言和包来保证线程安全。以下简单叙述一些本层次与上一层次的依赖(注意,synchronized因为JMM的优化可以分为3种) 1. final域 -> 内存屏障 2. volatile -> 内存屏障(字节码层次)-> 内存屏障(处理器层次) 3. synchronized -> 偏向锁 + 轻量级锁 + 互斥锁 偏向锁 -> CAS 轻量级锁 -> CAS 互斥锁 -> moniter -> 原子级处理器指令 4. concurrent包 -> volatile + CAS 注意CAS实现concurrent包中的原子操作可能会有三大问题: 1. ABA问题。(解决办法:在变量前增加版本号) 2. 循环时间长开销大。(解决办法:pause指令) 3. 只能保证一个共享变量的原子操作。(解决办法:用锁或着合并操作) JMM把各种控制程序顺序性的机制抽象成文字形式,就是happens-before。其目的就是向Java开发者屏蔽特定平台的底层细节,设计的程序只要遵守happens-before就可以保证正确性。
3. 程序员
这是最上面的层次,简单来说就是来利用好下层提供的机制来更好的编程。我想这也是我们要学习java并发原理的原因。
推荐阅读
-
深入分析java并发编程中volatile的实现原理
-
【编译原理】自底向上分析方法——LR文法分析方法的总结
-
Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析
-
java并发 - 自底向上的原理分析
-
【死磕Java并发】-----深入分析volatile的实现原理
-
【死磕Java并发】-----深入分析synchronized的实现原理
-
学习笔记(12):Java并发编程精讲-可定时执行的线程池原理分析
-
Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析
-
【死磕Java并发】-----深入分析synchronized的实现原理
-
【死磕Java并发】-----深入分析volatile的实现原理