JUC中的原子变量内部解析

  1. 云栖社区>
  2. 博客>
  3. 正文

JUC中的原子变量内部解析

鋒·Feng 2018-05-22 16:27:24 浏览1775
展开阅读全文

前言

工作中用到的一些原子操作类,查看一下它们的源码,顺便复习学习和梳理一下之前遗忘的知识点。

在Java中的java.util.concurrent.atomic包下面的原子操作类截图:

2a8bc17c6b3cfa4587e6dd23d0afad9faba3bc3d

主要知识点

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绕过安全检查器。


网友评论

登录后评论
0/500
评论
鋒·Feng
+ 关注