java并发编程读书心得,Java并发小结(一) -- 基本概念

这里整理下Java并发中的基本概念,以及个人的理解。

并发与并行

faabde4508fabec2ba2683591a3569fa.png

并行,指的是一个工作者同时做多件事情;并发指的是同一时刻多个工作者做多件事情。

对应到系统,比如说单个CPU,并行就是指单个CPU同时执行多个线程,在同一时间点,只会执行一个线程;并发指的是多个CPU同时执行多个线程。并发一定是并行的,并行的不一定是并发的。

内存可见性

这个概念初看,很容易就产生个疑问:难道内存还有不同见的情况?的确会有,需要了解这个问题,那就需要先了解下Java的内存模型:

04152255_O93C.png

线程、主内存、工作内存之间的关系如上图所示。 工作内存与主内存之间如果不同步,就会造成内存可见性问题: 如果线程A对共享变量X进行了修改,但是线程A没有及时把更新后的值刷入到主内存中,而此时线程B从主内存读取共享变量X的值,所以X的值是原始值,那么我们就说对于线程B来讲,共享变量X的更改对线程B是不可见的。

指令重排序

指令重排序包含两个方面:编译器重排与运行期重排。

编译期重排。编译源代码时,编译器依据对上下文的分析,对指令进行重排序,以之更适合于CPU的并行执行。

运行期重排,CPU在执行过程中,动态分析依赖部件的效能,对指令做重排序优化。

单看指令重排序这个概念,如果没有一定的限制,很明显指令重排序会使程序陷入混乱,没有办法理解,那怎么去限制指令重排序的范围呢,这个就要看下happens-before了。happens-before是在Java内存模型中定义好的, 在以下八种情况下,通过增加内存屏障指令,限制了指令重排序的范围:

同一个线程中的每个Action都happens-before于出现在其后的任何一个Action。

对一个监视器的解锁happens-before于每一个后续对同一个监视器的加锁。

对volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作。

Thread.start()的调用会happens-before于启动线程里面的动作。

Thread中的所有动作都happens-before于其他线程检查到此线程结束或者Thread.join()中返回或者Thread.isAlive()==false。

一个线程A调用另一个另一个线程B的interrupt()都happens-before于线程A发现B被A中断(B抛出异常或者A检测到B的isInterrupted()或者interrupted())。

一个对象构造函数的结束happens-before与该对象的finalizer的开始

如果A动作happens-before于B动作,而B动作happens-before与C动作,那么A动作happens-before于C动作。

volatile

可以使用volatile变量来解决内存可见性的问题,volatile描述符的主要作用:

保证被volatile修饰的共享gong’x变量对所有线程总数可见的,也就是当一个线程修改了一个被volatile修饰共享变量的值,新值总数可以被其他线程立即得知。

禁止指令重排序优化。

不能保证volatile变量符合操作的原子性。

原子性

这个概念在数据库里也有,一个操作要确保原子性,这个操作不能出现中间状态,要么操作全部成功,要么操作全部失败。比如a++,这个操作实际内部需要“读a->计算a+1->设置a”。要确保这个操作是原子性的,其它线程在对a进行操作时,只能在a++之前或之后对a进行操作,而不能在读 a之后或者设置a之前对a进行操作。

参考文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值