`

Java并发包Atomic 及Unsafe

 
阅读更多

  Java.util.concurrent.atomic下,有一堆AtomicXxxx对象。对于这些AtomicXxxx对象的使用,大家都知道,操作是线程安全的。不过大家有没有关心在多线程应用中,这些Atomic操作的线程安全是怎么实现的,究竟虚拟机是怎么来保证这些Atomic操作的呢?我们以AtomicLong为例,来分析Atomic操作究竟是怎么实现的。

大家可以仔细看看AtomicLong的源码,在AtomicLong中,定义了一个变量:

 

 

Private volatile long value
 

 

Volatile这个关键字的使用一直是爱恨交加,用得好的话事半功倍,如果用的不恰当则事倍功半。在此处,该value值是直接使用,不依赖外部变量的改变;并且该Value值直接放入Unsafe存储,直接和Memory打交道;和Memory打交道还有个能保证原子性的CAS的操作,所以volatile在此处使用刚好合适,volatile的其它使用场景请自行查找吧。这个value就是保存存入的值。另外还有这三个变量定义:

 

 

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static final Boolean VM_SUPPORT_LONG_CAS;
 

Ok,这四个变量定义就能够保证对long类型的原子操作。其中VM_SUPPORT_LONG_CAS变量实际上是表示该虚拟机是否支持CAS操作。Unsafe变量和valueOffset变量才是真正进行atomic操作的关键,操作的都是value值。下面我们来仔细分析下unsafevalueOffset



Unsafe类归属于sun.misc包,是JDK内部类,是限制使用的。我们需要将compiler选项限制级别降低,才能正常引用,想看Unsafe的源码请戳这里valueOffset表示的是操作的这个数据类型的偏移量,实际上就是数据类型所占的字节数2倍。

 

我们看到源码后,想获得Unsafe的实例,于是很高兴的写下了下面这个代码:

 

 

Unsafe unsafe = Unsafe.getUnsafe();
 

Sorry,你高兴的太早了,这个方法的使用是受限的,会抛出SecurityException,根本拿不到unsafe的实例。那怎么办呢?没关系,我们有万能的Reflection操作来实现。


正确的获得unsafe实例的代码应该如下:

 

 

       Unsafe unsafe = null;
        try {
            Field field;
            field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
 

 

看到unsafe的定义是private static final,这样的定义也能通过反射得到,那么变量作用范围声明关键字privateprotected还有什么用呢?以后大家如果想拿到某个被限制获得的类的话,要优先考虑reflection哦。其实我想说的是范围声明的关键字设定在reflection面前形同虚设,不知道这是不是符合Java的初衷,一家之言,仅供参考。


点开Unsafe源码,看到通篇native方法,仅有的几个非native方法,你再多看下还是native调用。这个native声明大家都不陌生,我们先看下的使用

 

 

 

        long value = 20121221L;
        byte size = 1;
        long address = unsafe.allocateMemory(size);
        System.out.println("Address:" + address);
        unsafe.putLong(address, value);
        long readValue = unsafe.getAddress(address);
        System.out.println("Value:" + readValue);
 

 

这个native方法的实现依赖于JVM,实现方法无从得知,但是从方法名字上可以看出来,这个unsafe实际上操作的是JVM的内存分配allocate、管理putget、拷贝copy、重分配reallocate和释放free。这个分配的内存没有进行初始化,并且能够自动类型对齐。很明显,这个操作和和Javanew Object操作完全不一样,反而和C++new操作一致;这块内存需要用户自己申请,自己进行操作。不同的是C++申请的是系统内存,而unsafe申请的是JVM控制的空间,那么这个native block是申请在stack上还是申请在heap上呢?大家可以思考一下。


看到这里,大家应该对于atomic原子操作的底层有了解了吧。其实Java也是可以通过APIC++一样直接操作虚拟机内存的。如果以后谁在告诉你Java不能直接操作内存的话,你可以以此为例给Ta一个耳光;更准确的应该说他们没有全部说对,应该说Java可以直接操作虚拟机控制的内存。


好吧,通过Unsafe操作确实能够保证赋值、读值的原子操作,等等,这就完了?No,麻烦大家看下AtomicXxxx的 getAndSet、 getAndIncrement、 getAndDecrement、  getAndAdd等方法操作,发现并不是直接委托给unsafe处理,而是添加了一些额外的操作。这些额外的操作究竟是什么意思?用的还是循环处理操作直到成功为止。这个操作有什么玄机,或者说其它的理论支持呢?且看我们下次分析。


 

 

 

 

 

 

 

分享到:
评论

相关推荐

    java线程-Atomic的含义及示例_.docx

    java线程-Atomic的含义及示例_.docx

    Java多线程atomic包介绍及使用方法

    主要介绍了Java多线程atomic包介绍及使用方法,涉及原子更新基本类型介绍及代码示例,具有一定参考价值,需要的朋友可以了解下。

    浅谈Java中的atomic包实现原理及应用

    主要介绍了浅谈Java中的atomic包实现原理及应用,涉及Atomic在硬件上的支持,Atomic包简介及源码分析等相关内容,具有一定借鉴价值,需要的朋友可以参考下。

    Java多线程Atomic包操作原子变量与原子类详解

    主要介绍了Java多线程Atomic包操作原子变量与原子类详解,简单介绍了Atomic,同时涉及java.util.concurrent中的原子变量,Atomic类的作用等相关内容,具有一定参考价值,需要的朋友可以了解下。

    Java Atomic类及线程同步新机制原理解析

    主要介绍了Java Atomic类及线程同步新机制原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    atomic

    atomic

    Java并发编程包中atomic的实现原理示例详解

    主要给大家介绍了关于Java并发编程包中atomic的实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    JAVA_API1.6文档(中文)

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 ...

    Atomic

    Atomic

    Java 1.6 API 中文 New

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR ...

    Sparklingredstar#JavaBooks#Java多线程-Atomic原子类1

    引言JavaGuide :一份涵盖大部分Java程序员所需要掌握的核心知识。star:45159,替他宣传一下子这位大佬,总结的真好!我引用这位大佬的文章,因为

    atomic scala

    Atomic Scala eBook 编程思想的作者新书

    Java面试题+Java并发编程(J.U.C)+Java8实战+Redis+kafka

    『死磕Java并发编程系列』 04 面试官:说说Atomic原子类的实现原理? 『死磕Java并发编程系列』 05 图解Java中那18 把锁.md 『死磕Java并发编程系列』06 倒计时计数CountDownLatch 『死磕Java并发编程系列』07 人齐...

    JavaAPI1.6中文chm文档 part1

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 ...

    volatile,nonatomic和atomic关键字测试

    主要研究四种变量(属性)的存取速度. volatile nonatomic atomic和正常变量

    java.util.concurrent

    java.util.concurrent总体概览图。 收取资源分3分。需要的同学可以下载一下。 java.util.concurrent主要包括5个部分executor,colletions,locks,atomic...该图详细的列举了并发包下面的结构,包含所有接口和具体实现类。

    java api最新7.0

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR ...

    boost_atomic.7z

    来自BOOST库的原子操作atomic的源代码,跨平台

    前端开源库-atomic-batcher

    前端开源库-atomic-batcher原子批处理程序,一个简单的批处理函数,允许您自动批处理一系列操作。

    msvcp140_atomic_wait.dll下载 找不到msvcp140_atomic_wait.dll .zip

    dll控件常规安装方法(仅供参考): 一、如果在运行某软件或编译程序时提示缺少、找不到dll等类似提示,您可将下载来的dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或者重新添加文件引用...

Global site tag (gtag.js) - Google Analytics