每日学习20170302--volatile关键字

Volatile关键字

1.并发问题

当多个线程访问共享内存的时候,会出现并发问题。代码如下:

每日学习20170302--volatile关键字_第1张图片

执行多次发现结果不同,并且不是预期的100,而是比小于100。

 

2.增加volatile关键字

有一个误区认为加上volatile之后就可以防止并发问题。我们把例子稍作修改,在count变量上增加volatile关键字,再次执行发现并发问题仍然没有解决。

 

3.并发问题产生原因

首先,jvm本身有一块主内存,而多线程的时候,每个线程有自己的内存区域。当线程需要读写主内存的变量时,流程如下:

1)  线程将主内存的变量拷贝一份到线程内存。

2)  线程内存执行操作。

3)  线程内存将变量同步到主内存。

那么没有任何保护措施的情况下,读取时和修改后两个节点都有可能出现当前线程内存与主内存之间的一致性问题。最终造成了并发问题。

 

4.引入volatile之后

volatile关键字修饰变量之后,一旦内存中拷贝的变量发生变化,会立即造成其他线程中对此变量拷贝的失效,其他线程中读取此变量的时候就会到主内存中去重新拷贝。因此volatile能够保证共享变量的可见性,但并不能保证其原子性。换句话说能够保证对于变量的读取永远是最新的,但不能保证非原子操作的一致性。

在逻辑上我们可以这么理解,如果用synchronized来处理,那么执行count++时,count在主内存中的值,由读到写,全都只能被一个线程访问。是可以保证一致性的。用volatile修饰时,只是相当于当一个线程改变count值的时候,发出了消息让其他线程更新本地的count值,而其他线程中已经执行过的count赋值语句则不受任何影响,因此仍然会出现并发问题。

你可能感兴趣的:(java开发)