一、原子变量
在Java并发编程实战中线程安全的定义是这样的:当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用该代码不必做其它的协调,这个类的行为仍然是正确的,那么这个类就是线程安全的。由这定义我们可以知道,显然只有资源竞争时才会导致线程不安全,因此无状态对象永远是线程安全的。
原子操作的描述:多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。也就是原子类操作是不能被线程调度机制中断的操作。
原子变量类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。
类 AtomicBoolean、 AtomicInteger、 AtomicLong 和 AtomicReference 的实例各自提供对相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。
AtomicIntegerArray、 AtomicLongArray 和 AtomicReferenceArray 类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。
核心方法: boolean compareAndSet(expectedValue, updateValue)
java.util.concurrent.atomic 包下提供了一些原子操作的常用类:
AtomicBoolean 、 AtomicInteger 、 AtomicLong 、 AtomicReference
AtomicIntegerArray 、 AtomicLongArray
AtomicMarkableReference
AtomicReferenceArray
AtomicStampedReference
案例解析:
改进方案:
二、CAS算法:
CAS (Compare-And-Swap) 是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问。
CAS 是一种无锁的非阻塞算法的实现。
CAS 包含了 3 个操作数:
需要读写的内存值 V
进行比较的值 A
拟写入的新值 B
当且仅当 V 的值等于 A 时, CAS 通过原子方式用新值 B 来更新 V 的值,否则不会执行任何操作
// 模拟CAS 算法
classCompareAndSwap{
privateintvalue;
// 获取内存值
publicsynchronizedintget(){
returnvalue;
}
// 无论更新成功与否,都返回修改之前的内存值
publicsynchronizedintcompareAndSwap(intexpectedValue,intnewValue){
// 获取旧值
intoldValue =value;
if(oldValue == expectedValue){
this.value= newValue;
}
// 返回修改之前的值
returnoldValue;
}
// 判断是否设置成功
publicsynchronized booleancompareAndSet(intexpectedValue,intnewValue){
returnexpectedValue == compareAndSwap(expectedValue, newValue);
}
}
publicclassTestCompareAndSwap{
publicstaticvoidmain(String[] args){
final CopareAndSwap cas =newCompareAndSwap();
for(inti=; i
// 创建10个线程,模拟多线程环境
newThead(newRunnable(){
publicvoidrun(){
intexpectedValue = cas.get();
boolean b = cas.compareAndSet(expectedValue, (int)(Math.random()*100));
System.out.println(b); } }).start(); } }}
领取专属 10元无门槛券
私享最新 技术干货