RequestQueue中第一行代码
private AtomicInteger mSequenceGenerator = new AtomicInteger();
用来产生一个自增的计数,这里用AtomicInteger主要考虑到应用场景为高并发,使用普通count++
计数会出现问题。那么AtomicInteger是怎么处理高并发的场景呢?
我们来看下这个类的几处核心代码
public class AtomicInteger extends Number implements java.io.Serializable {...}
private volatile int value;
volatile关键字volatile-百度百科
这个关键字是一个用起来很复杂的东西,应用它需要考虑很多东西,功能简单来说是用来定义这个关键字是线程安全的,实现方法是每次使用它都要从内存中读取,每次它的值发生变化都要写到内存中,藉此来保证读取的值是同样的。
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); }
}
我们来看下Unsafe这个类,它是在sun.misc package下面的,它的成员函数多是native的,因为这个类主要是快速实现读取内存地址的。
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
上面的CAS算法(比较并交换)是核心方法,同时可以从主要函数可以看出来AtomicInteger应对高并发的策略是强制读取内存中的值来保证一致性,采用的是非阻塞算法简介。使用硬件生成来达到原子性。(非阻塞操作由于其本身的原子性可以代替锁定方法来保证线程安全,另一个大话题不在这里讨论~)