在变成过程当中咱们须要保证变量的线程安全,在java中除了使用锁机制或者Threadlocal等保证线程安全,还提供了java
java.util.concurrent.atomic.Atomic*(如AtomicInteger,AtomicLong等)原子类和volatile关键字是java中安全
两种常见的处理多线程下数据共享读写的机制。多线程
两者看似相同,可是在实际应用中有着不小的差异。测试
1.volatile关键字atom
volatile关键字是经过本地代码实现的写锁,只保证知有一个线程在写某个数据。JVM为了提升数据存取的速度,spa
容许每一个线程在本身独立的数据块,对进程中共享的数据进行私有拷贝。volatile就是保证每次读数据时,线程
读的都是存在共享数据块里的数据,而不是私有拷贝。然而,这种机制在有些状况下并不安全。设计
当两个线程T1,T2同时对volatitle int i;做i++;时,可能出现问题。i++至关于为i=i+1。code
T1 load i T2 load i T1 store i+1 T2 store i+1
这里应该执行两次i=i+1,获得i=i+2的,可是结果确实i=i+1。blog
所以,这边就有了Atomic原子类存在的价值了。Atomic类被设计来解决这个问题。
2.Atomic* 原子操做
关于atomic*原子操做,这里以AtomicInteger类为例
使用场景:
AtomicInteger,一个提供原子操做的Integer的类。在Java语言中,++i和i++操做并非线程安全的,在使用的时候,
不可避免的会用到synchronized关键字。而AtomicInteger则经过一种线程安全的加减操做接口。
/**
* Atomic原子性测试。
*
* @author cary
* @version 1.0.0
*/
public class AtomicTest {
public static void main(String[] args) { AtomicInteger ai = new AtomicInteger(0); int i1 = ai.get(); print(i1); int i2 = ai.getAndSet(5); print(i2); int i3 = ai.get(); print(i3); int i4 = ai.getAndIncrement(); print(i4); print(ai.get()); } static void print(int i) { System.out.println("i : " + i); } }
结论: atomic比volatile靠谱