原子类的作用和锁类似,是为了保证并发情况下线程安全。不过原子类相比于锁,有一定的优势︰
1.粒度更细:原子变量可以把竞争范围缩小到变量级别,这是我们可以获得的最细粒度的情况了,通常锁的粒度都要大于原子变量的粒度
2.效率更高:通常,使用原子类的效率会比使用锁的效率更高,除了高度竞争的情况
一、基本类型原子类
常用方法:
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 )
AtomicInteger
示例:
/**演示示AtomicInteger的基本用法,对比非原子类的线程安全问题,使用了原子类之后,不需要加锁,也可以保证线程安全*/
public class AtomicIntegerDemo implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new AtomicIntegerDemo());
Thread thread2 = new Thread(new AtomicIntegerDemo());
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("原子类的结果:" + atomicInteger.get());
System.out.println("普通变量的结果:" + basicCount);
}
public static final AtomicInteger atomicInteger = new AtomicInteger();
private static volatile int basicCount = 0;
public void incrementAtomic(){
atomicInteger.getAndIncrement();
}
public void incrementBasic(){
basicCount++;
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
incrementAtomic();
incrementBasic();
}
}
}
结果:----------
原子类的结果:20000
普通变量的结果:19089
可以看到,原子类保持了线程安全。