1 Atomic 原子类介绍( 二 )


【1 Atomic 原子类介绍】输出内容如下:
Thread-0 ------ currentValue=http://www.kingceram.com/post/1Thread-1 ------ currentValue=1, finalValue=2, compareAndSet Result=trueThread-1 ------ currentValue=2, finalValue=1, compareAndSet Result=trueThread-0 ------ currentValue=1, finalValue=2, compareAndSet Result=true
下面我们来详细介绍一下这些原子类 。
2 基本类型原子类 2.1 基本类型原子类介绍
使用原子的方式更新基本类型
上面三个类提供的方法几乎相同 , 所以我们这里以为例子来介绍 。

1 Atomic 原子类介绍

文章插图
类常用方法
public final int get() //获取当前的值public final int getAndSet(int newValue)//获取当前的值 , 并设置新的值public final int getAndIncrement()//获取当前的值 , 并自增public final int getAndDecrement() //获取当前的值 , 并自减public final int getAndAdd(int delta) //获取当前的值 , 并加上预期的值boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值 , 则以原子方式将该值设置为输入值(update)public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值 。
2.2常见方法使用
import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerTest {public static void main(String[] args) {// TODO Auto-generated method stubint temvalue = http://www.kingceram.com/post/0;AtomicInteger i = new AtomicInteger(0);temvalue = i.getAndSet(3);System.out.println("temvalue:" + temvalue + ";i:" + i);//temvalue:0;i:3temvalue = http://www.kingceram.com/post/i.getAndIncrement();System.out.println("temvalue:" + temvalue + ";i:" + i);//temvalue:3;i:4temvalue = http://www.kingceram.com/post/i.getAndAdd(5);System.out.println("temvalue:" + temvalue + ";i:" + i);//temvalue:4;i:9}}
2.3 基本数据类型原子类的优势
通过一个简单例子带大家看一下基本数据类型原子类的优势
①多线程环境不使用原子类保证线程安全(基本数据类型)
class Test {private volatile int count = 0;//若要线程安全执行执行count++ , 需要加锁public synchronized void increment() {count++; }public int getCount() {return count;}}
②多线程环境使用原子类保证线程安全(基本数据类型)
class Test2 {private AtomicInteger count = new AtomicInteger();public void increment() {count.incrementAndGet();}//使用AtomicInteger之后 , 不需要加锁 , 也可以实现线程安全 。public int getCount() {return count.get();}}
2.4线程安全原理简单分析
类的部分源码:
// setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用)private static final Unsafe unsafe = Unsafe.getUnsafe();private static final long valueOffset;static {try {valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }}private volatile int value;
类主要利用 CAS ( and swap) +和方法来保证原子操作 , 从而避免的高开销 , 执行效率大为提升 。
CAS的原理是拿期望的值和原本的一个值作比较 , 如果相同则更新成新的值 。类的 () 方法是一个本地方法 , 这个方法是用来拿到“原来的值”的内存地址 。另外 value 是一个变量 , 在内存中可见 , 因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值 。