并发编程的三个概念

Java并发编程常说的,在实际开发中需要经常注意的三个概念:原子性、可见性、有序性。

1、原子性
原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。
在java中,对基本数据类型的赋值和读取时原子性的。

分析以下代码,判断哪些是原子性的
x=10;//语句1
y=x;//语句2
x++;//语句3
x=x+1;//语句4

看到上面的代码可能小伙伴们会说都是原子性的,实则不然,只有语句1是原子性的。
x=10,线程执行这个语句时直接把数值10写入工作内存
y=x,线程执行这个语句时,首先从工作内存中读取x的值,再将x的值写入到工作内存,虽然这两个操作都是原子性的,但是合起来就不是了。
x++,线程执行这个语句时,本质上执行了三个动作,先把x从工作内存中读取,在进行+1,再把最后的结果写入到工作内存。

也就是说,在java的内存模型中,只有对基本数据类型的简单读取和赋值是原子性的(相互赋值不是原子性)。

实现大范围原子性的方法:
悲观锁(synchronized或者Lock)
乐观锁(原子类 cas)

2、可见性
可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。

当多个线程操作一个普通的共享变量时,其中某个线程操作的原理是这样的,首先从主内存中读取这个变量到自己的工作内存,在工作内存中修改以后保留变量的副本,在写入到主内存。但是普通变量不存在可见性,当修改新值以后,什么时候写入主内存是不一定的,当其他线程读取的时候,读取的可能还是旧值。

实现可见性的方法:
synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。
volatile:被volatile修饰的变量,一个线程修改后直接把值写入主内存,其他线程直接从主内存中读取。

3、有序性
有序性,即程序的执行顺序按照代码的先后顺序来执行。
在java内存模型中,编译器和处理器允许对指令进行重排序,在单线程下不会出问题,但是多线程下会有问题。

实现有序性的方法:
synchronized或者Lock
volatile(禁止指令重排序)

你可能感兴趣的:(并发编程)