前言
工作中用到的一些原子操作类,查看一下它们的源码,顺便复习学习和梳理一下之前遗忘的知识点。
在Java中的java.util.concurrent.atomic包下面的原子操作类截图:
主要知识点
1.原子变量
在Java代码中保证线程安全一般分成两种方式:锁和原子变量,这次的主题是原子变量。
原子变量能够保证原子性的操作,意思是某个任务在执行过程中,要么全部成功,要么全部失败回滚,恢复到执行之前的初态,不存在初态和成功之间的中间状态。例如CAS(Compare and Swap)操作,要么比较并交换成功,要么比较并交换失败。由CPU保证原子性。
通过原子变量可以实现线程安全。执行某个任务的时候,先假定不会有冲突,若不发生冲突,则直接执行成功;当发生冲突的时候,则执行失败,回滚再重新操作,直到不发生冲突。
2.CAS
CAS(Compare and Swap),一种无锁(lock-free)的非阻塞算法,翻译为:比较和交换。并且是CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令。
CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
CAS无锁算法的C实现:
int compare_and_swap (int* reg, int oldval, int newval)
{
ATOMIC();
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
END_ATOMIC();
return old_reg_val;
}
JVM对CAS的支持体现从JDK1.5中引入了底层的支持,在int、long和对象的引用等类型上都公开了CAS的操作,并且JVM把它们编译为底层硬件提供的最有效的方法。
3.魔法类:sun.misc.Unsafe
在原子变量中的方法底层实现的是利用Unsafe的CAS来实现原子操作的,其中Unsafe.compareAndSwap()用来实现高效的无锁数据结构。
这个类的提供了一些绕开JVM的更底层功能,直接申请和操作物理内存,基于它的实现可以提高效率。它所分配的内存需要手动free(不被GC回收)。
Unsafe的简单介绍:
(1)Unsafe类设计只提供给JVM信任的启动类加载器所使用,是一个典型的单例模式类;
(2)在Java中,可以用Unsafe绕过安全检查器。