多线程基础概念

Java 内存模型中的可见性、原子性和有序性。

可见性 :
是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。
在 Java 中 volatile、synchronized 和 final 实现可见性。


原子性:
原子是世界上的最小单位,具有不可分割性。
比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。AtomicInteger、AtomicLong、AtomicReference并发包的类提供了原子操作API。
在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性。


有序性:
多个线程的执行顺序,是重排序的。比如,主线程定义了2个变量a=0,b=0;线程 A,将执行 a=2,b=1;B线程将执行while(a=2){b=3},这是可能b线程a的值不确定。Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性。

安全发布的常用模式:
在静态初始化函数中初始化一个对象引用
将对象的应用保存到volatile类型的域或者AtomicReferance对象中
将对象的引用保存到某个正确构造对象的final类型域中
将对象的引用保存到一个由锁保护的域中。

与volatile相比较,对final域的读和写更像是普通的变量访问。对于final域,编译器和处理器要遵守两个重排序规则:
在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。

与Volatile 有相似作用,不过Final主要用于不可变变量(基本数据类型和非基本数据类型),进行安全的发布(初始化)。而Volatile可以用于安全的发布不可变变量,也可以提供可变变量的可见性。

猜你喜欢

转载自u011997289.iteye.com/blog/2399410