JAVA提供了一个原子化包,支持在单个变量上接触锁定的线程安全编程。效果应该要好于volatile,因为volatile只能保证提取最新的值,而原子化变量却可以保证变量内状态的操作的原子性。
原子化的变量类型并不是真正对应的类型,如:AtomicBoolean与真正的Boolean,没有直接的关系,更无从与继承什么的亲密关系了。所以对于常见的类型的操作这里不一定会提供,这是需要注意的。而且由于原子化变量需要操控内部的状态,所以一个对象内部状态是经常性变化的,所以也就没有提供hashCode方法。
相对于volatile针对变量的读取来说,原子化类型在类型内封装了一些常用的原子化操作。是一种同步手段。
在设置值的是时候不会单纯的进行设置操作,而是首先进行一下比较,类似于我们的synchronized中先判别值是否发生变化,然后再设值的操作。比如AtomicBoolean:
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
不同的原子化类对象提供了不同的访问等操作方法,但大体思路还是差不多的,原子访问和更新的内存效果一般遵循以下可变规则:
- get 具有读取 volatile 变量的内存效果。
- set 具有写入(分配) volatile 变量的内存效果。
- weakCompareAndSet 以原子方式读取和有条件地写入变量,并对于该变量上的其他内存操作进行排序,否则将充当普通的非可变内存操作。
- compareAndSet 和所有其他的读取和更新操作(如 getAndIncrement)都有读取和写入 volatile 变量的内存效果。
主要的原子类型有:
- AtomicBoolean
- AtomicInteger
- AtomicLong
- AtomicReference
- AtomicMarkableReference
- AtomicStampedReference
--array
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
--file_update
- AtomicIntegerFileUpdater
- AtomicLongFileUpdater
- AtomicReferenceFileUpdater