满足同步三个基本条件:
1.原子性
原子性是指操作是不可分的。其表现在于对于共享变量的某些操作,应该是不可分的,必须连续完成。例如a++,对于共享变量a的操作,实际上会执行三个步骤,1.读取变量a的值 2.a的值+1 3.将值赋予变量a 。 这三个操作中任何一个操作过程中,a的值被人篡改,那么都会出现我们不希望出现的结果。所以我们必须保证这是原子性的。
2.可见性:一个线程对共享变量值得修改,能够及时的被其他线程看到
多线程高并发中,线程之间的通信是靠内存共享,即一个对象或变量,它在堆中的主内存中,每一个请求可以看做一个线程,每一个线程,都想操作这个主内存的对象或变量,线程会复制一份主内存中的对象或变量,到自己的线程本地栈内存中,直到操作完毕,才会将本地栈内存的对象或变量,赋值给主内存。如果不加同步锁,主内存中的对象或变量,值就容易被最后提交操作的线程覆盖,发生错误。
3.有序性:
指令重排序:代码书写的顺序与实际执行的顺序不同,指令重排序是编译器或处理器为了提高程序性能而做的优化。
1.编译器优化的重排序(编译器优化)
2.指令级并行重排序(处理器优化)
3.内存系统的重排序(处理器优化)
是不是所有的语句的执行顺序都可以重排呢?
答案是否定的。为了讲清楚这个问题,先讲解另一个概念:数据依赖性
什么是数据依赖性?
如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖。数据依赖分下列三种类型:
| 名称 | 代码示例 | 说明 |
| 写后读 | a = 1;b = a; | 写一个变量之后,再读这个位置。 |
| 写后写 | a = 1;a = 2; | 写一个变量之后,再写这个变量。 |
| 读后写 | a = b;b = 1; | 读一个变量之后,再写这个变量。 |
上面三种情况,只要重排序两个操作的执行顺序,程序的执行结果将会被改变。所以,编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。也就是说:在单线程环境下,指令执行的最终效果应当与其在顺序执行下的效果一致,否则这种优化便会失去意义。这句话有个专业术语叫做as-if-serial semantics (as-if-serial语义)
int num1=1;//第一行
int num2=2;//第二行
int sum=num1+num;//第三行
单线程:第一行和第二行可以重排序,但第三行不行
重排序不会给单线程带来内存可见性问题
多线程中程序交错执行时,重排序可能会照成内存可见性问题。
synchronized关键字:
synchronized通过操作对象锁和类对象锁,修饰方法和代码块,则保证持有锁的线程操作完毕,重新赋值主内存中的对象或变量后,其他线程再去争抢锁,继续操作主内存对象。达到一个线程的执行结果对其他线程的。满足上面的三个原则。
volatile变量每次被线程访问时,都强迫从主内存中读取该变量的值,而当变量发生变化的时候都会强迫线程将最新的值刷新到主内存中。
这样不同的变量总能看到最新的值。
可以把volatile变量的单个读写,看成是使用同一个锁对这些单个读/写操作做了同步。
volatile关键字:
- 能够保证volatile变量的可见性
- 只能保证单个volatile变量的原子性,对于volatile++这种复合操作不具有原子性
-
对volatile变量执行写操作时,会在写操作后加入一条store屏障指令
- store指令会在写操作后把最新的值强制刷新到主内存中。同时还会禁止cpu对代码进行重排序优化。这样就保证了值在主内存中是最新的。
-
对volatile变量执行读操作时,会在读操作前加入一条load屏障指令
- load指令会在读操作前把内存缓存中的值清空后,再从主内存中读取最新的值。


synchronized和volatile的比较:
- synchronized锁住的是变量和变量的操作,而volatile锁住的只是变量,而且该变量的值不能依赖它本身的值,volatile算是一种轻量级的同步锁
- volatile不需要加锁,比synchronized更加轻量级,不会阻塞线程。
- 从内存可见性角度讲,volatile读相当于加锁,volatilexie相当于解锁。
- synchronized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性。
注:由于voaltile比synchronized更加轻量级,所以执行的效率肯定是比synchroized更高。在可以保证原子性操作时,可以尽量的选择使用volatile。在其他不能保证其操作的原子性时,再去考虑使用synchronized。
来源:oschina
链接:https://my.oschina.net/u/3156785/blog/3031799