关于Java中的原子性、可见性

关于Java中的原子性、可见性的学习

固然原子性、可见性不只限于Java的并发编程中,这三种性质的问题是在全部并发编程中广泛拥有的。java

原子性

在Java中,对基本数据的读取与赋值操做是原子性的。算法

你们都知道原子是天然界中很基本的单位。数据库

那什么是原子性呢?学习过数据库相关知识的人应该都知道数据库事务中有ACID四个基本要素,其中A就是咱们所说的原子性(Atomicity),数据库事务中,原子性的意思就是:一个事务,要么执行,要么不执行。简单说就是不存在执行到一半的状况,一个事务就是最小的单元。编程

“要么有,要么无。”缓存

首先咱们须要知道: 在Java中,对基本数据的读取与赋值操做是原子性的。多线程

好比下面的代码:并发

int i = 1;

把1赋值给i这个操做就是原子性的。学习

那就有同窗要问了:这就一句代码,怎么看都是一步操做到位,这不是明摆着就是“原子性”吗?atom

非也非也,咱们假设赋值这个int类型的值时,是先赋值给低16位,再赋值给高16位,这样一来,就成了两步操做。若是恰好赋值给低16位的时候线程断了,那么i所赋的值就不必定是你想赋的值了。线程

是否是立刻感受到了原子性的重要性?

这里须要注意的是Java中,自增语句不是原子性的:

i++;

实际上,自增是两个操做,首先读取i的值,而后再是赋值给i,两个步骤都是具备原子性的,可是两个原子性操做在一块儿就再也不拥有原子性。

正确的方法可使用java.util.concurrent.atomic包中的好比AtomicInteger类,它可让赋值读取具备原子性。

可见性

在Java中,解决可见性问题的方法就是在你所需多线程访问的变量在添加volatile关键词。

咱们试想一下,当CPU老是去访问物理内存去获取变量,而后频繁地去修改物理内存上的值,是否是太麻烦了?这将致使CPU花大部分的时间在获取和修改物理内存的值。

因此,如今的CPU内部广泛它本身的内存空间,咱们称之为 “CPU缓存”

那CPU缓存有什么做用?百度百科中这样描述:

CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多可是交换速度却比内存要快得多。高速缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,由于CPU运算速度要比内存读写速度快不少,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的一小部分,但这一小部分是短期内CPU即将访问的,当CPU调用大量数据时,就可先缓存中调用,从而加快读取速度。

一句话说就是,让CPU处理指令更快更快更快更快更快更快更快更快。

** 可是与之而来的就是并发编程在多核CPU中的可见性问题。 ** 由于如今的电脑都是多核处理器,也就是一个CPU内部是由多个CPU组合而成。

不妨咱们作一个这样的假设:

// Thread1
int i = 1;
i = 10;

// Thread2
int j = i;

咱们假定线程1在CPU1中执行,线程2在CPU2中执行。

具体流程以下:

  1. 首先线程1定义了i并将1赋值给了i,此时i被载入到主存(也就是物理上的内存)

  2. 而后线程1执行“i=10”语句,CPU1会将修改后的i放入CPU缓存中,注意:并无直接载入到主存。

  3. 线程2中先获取i的值,CPU2缓存中没有i,因此就去获取主存中的i值,然而主存中仍是i=1,这样,j就被赋值为1。

流程结束。如今咱们应该知道了什么是可见性问题,并能感觉到问题的严重性。

** 事实上,很难模拟出这样的结果。 ** 由于咱们没法让某个线程指定某个特定CPU,这是系统底层的算法,我想JVM应该也是无法控制的。还有最重要的一点,就是你没法预测CPU缓存什么时候会将值传给主存,可能这个时间间隔很是短,短到你没法观察到。还有就是线程的执行的顺序问题,由于多线程你没法控制哪一个线程的某句代码会在另外一个线程的某句代码后面立刻执行。

那么如何才能避免上述状况?

Java提供volatile关键词,只要将这个关键词修饰在你考虑会出现这个问题的变量声明前,就能够避免可见性问题。

volatile int i = 1;

当添加该关键词后,JVM会得知这个变量须要确保在应用中的可见性,而后通知系统:”这个变量直接在主存读取修改,别放到CPU缓存里了“。

“yes,sir!”

而后就不须要考虑可见性问题了。

固然解决可见性问题还有一招更灵,就是让这个域彻底由synchronized方法或代码块来维护,那就没必要在将其设置为volatile了。 由于同步会致使向主存中刷新。

注意:当一个域的值依赖于它以前的值时(例如递增一个计数器),volatile就没法工做了。

相关文章
相关标签/搜索