在阅读AtomicInteger的源码时,看到了这个类:sum.msic.Unsafe,之前从没见过。所以花了点时间google了一下。

Unsafe的源码:http://www.docjar.com/html/api/sun/misc/Unsafe.java.html

Unsafe源码中的描述如下:

 写道
A collection of methods for performing low-level, unsafe operations. Although the class and all methods are public, use of this class is limited because only trusted code can obtain instances of it.

这个类是用于执行低级别、不安全操作的方法集合。尽管这个类和所有的方法都是公开的(public),但是这个类的使用仍然受限,你无法在自己的java程序中直接使用该类,因为只有授信的代码才能获得该类的实例。

从上面的描述,可以了解到该类是用来执行较低级别的操作的,比如获取某个属性在内存中的位置,不过一般人很少会有这样的需求。在AtomicInteger的源码中相关的代码如下:

  1. // setup to use Unsafe.compareAndSwapInt for updates
  2. private static final Unsafe unsafe = Unsafe.getUnsafe();

上面这行代码是获取Unsafe实例的。一般情况下,我们是拿不到该类的实例的,当然jdk库里面是可以随意使用的。

  1. static {
  2. try {
  3. valueOffset = unsafe.objectFieldOffset
  4. (AtomicInteger.class.getDeclaredField("value"));
  5. } catch (Exception ex) { throw new Error(ex); }
  6. }

上面这几行代码,是用来获取AtomicInteger实例中的value属性在内存中的位置。这里使用了Unsafe的objectFieldOffset方法。这个方法是一个本地方法, 该方法用来获取一个给定的静态属性的位置。

  1. public native long objectFieldOffset(Field f);

这里有个疑问,为什么需要获取属性在内存中的位置?通过查看AtomicInteger源码发现,在这样几个地方使用到了这个valueOffset值:

  1. public final void lazySet(int newValue) {
  2. unsafe.putOrderedInt(this, valueOffset, newValue);
  3. }
  1. public final boolean compareAndSet(int expect, int update) {
  2. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  3. }
  1. public final boolean weakCompareAndSet(int expect, int update) {
  2. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  3. }

查找资料后,发现lazySet方法大多用在并发的数据结构中,用于低级别的优化。compareAndSet这个方法多见于并发控制中,简称CAS(Compare And Swap),意思是如果valueOffset位置包含的值与expect值相同,则更新valueOffset位置的值为update,并返回true,否则不更新,返回false。(valueOffset代表内存地址)

这里可以举个例子来说明compareAndSet的作用,如支持并发的计数器,在进行计数的时候,首先读取当前的值,假设值为a,对当前值 + 1得到b,但是+1操作完以后,并不能直接修改原值为b,因为在进行+1操作的过程中,可能会有其它线程已经对原值进行了修改,所以在更新之前需要判断原值是不是等于a,如果不等于a,说明有其它线程修改了,需要重新读取原值进行操作,如果等于a,说明在+1的操作过程中,没有其它线程来修改值,我们就可以放心的更新原值了。

Unsafe类中还包含有很多其它的方法,如果想使用其中的方法,可以通过反射机制拿到Unsafe中的一个静态属性theUnsafe ,这个静态属性本身已经初始化了,所以拿到以后可以直接使用。

Java中的Unsafe的更多相关文章

  1. Java中的Unsafe类111

    1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoo ...

  2. Java中的Unsafe在安全领域的一些应用总结和复现

    目录 0 前言 1 基本使用 1.1 内存级别修改值 1.2 创建对象 1.3 创建VM Anonymous Class 2 利用姿势 2.1 修改值以关闭RASP等防御措施 2.2 创建Native ...

  3. 关于java中的锁(转)

    对于锁一直处于比较模糊的状态,最近一天晚上偶然想看看,就翻了几本书,然后弄明白了一些概念,有一些仍然没明白,例如AQS,先把搞明白的记录一下吧. 什么是线程安全? 当多个线程访问一个对象时,如果不用考 ...

  4. 【Java并发】Java中的原子操作类

    综述 JDK从1.5开始提供了java.util.concurrent.atomic包. 通过包中的原子操作类能够线程安全地更新一个变量. 包含4种类型的原子更新方式:基本类型.数组.引用.对象中字段 ...

  5. 从同步原语看非阻塞同步以及Java中的应用

    非阻塞同步:基于冲突检测的乐观并发策略,通俗讲就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了,如果争用数据有冲突那就采用其他的补偿措施(最常见的就是不断重试直到成功),这种乐观的并发策略 ...

  6. 【实战Java高并发程序设计 1】Java中的指针:Unsafe类

    是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...

  7. Java中Unsafe类详解

    http://www.cnblogs.com/mickole/articles/3757278.html Java不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe类提供了硬件级别的原子操 ...

  8. 【Java深入研究】8、Java中Unsafe类详解

    java不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe类提供了硬件级别的原子操作,主要提供了以下功能: 1.通过Unsafe类可以分配内存,可以释放内存: 类中提供的3个本地方法all ...

  9. [java] java 中Unsafe类学习

    java不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe类提供了硬件级别的原子操作,主要提供了以下功能: 1.通过Unsafe类可以分配内存,可以释放内存: 类中提供的3个本地方法all ...

随机推荐

  1. java操作mongodb——查询数据

    通过find方法查询集合中的文档信息 -------------------------------------------------------- find() 查询所有文档信息,返回FindIt ...

  2. 运行ORB-SLAM笔记_编译篇(一)

    1.下载代码   https://github.com/raulmur/ORB_SLAM/    (同时也可以看看作者的牛叉论文,我是打算先用代码,再回头看论文) 2.打开后如下 就好像是用一件新产品 ...

  3. 在Eclipse中用TODO标签管理任务(Task)

    Elipse为Java项目的时候,有一个很人性化的“任务管理”功能,利用这个功能可以方便地将项目中一些需要处理的任务记录下来.先来看看“任务管理”是怎么使用的吧.下面这个类在Class和name 属性 ...

  4. C#在客户端验证数字证书(Certificate)

    ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallback;//Init时执行,用于 ...

  5. GNU Octave fact函数输出

    无意间发现了这么一个函数,可以随机输出关于RMS的笑话.挺有意思的. `fact' is a function from the file /usr/share/octave/3.6.2/m/misc ...

  6. TreeSet与TreeMap的源码分析 JDK7

    TreeSet存储原则是:不可重复,有序的. public TreeSet() { this(new TreeMap<E,Object>()); } public TreeSet(Comp ...

  7. x264宏块及子块划分方式

    1 宏块划分方式 一副图像(帧,非场图像,x264支持宏块级场编码,这里以帧图像为例说明)按从左到右.从上到下16x16的方式划分宏块,对于图像宽度不是16的倍数的情况,会扩展至16的倍数,然后通过s ...

  8. OOP in JS Public/Private Variables and Methods

    Summary private variables are declared with the 'var' keyword inside the object, and can only be acc ...

  9. xfs文件系统磁盘配额

    引言 这篇文章简单介绍一下xfs文件系统的磁盘配额配置. 文章目录 0×1.开启分区磁盘配额 0×2.使用xfs_quota命令配置磁盘配额 0×1.开启分区磁盘配额 对于ext4文件以前的文件系统, ...

  10. css的三大特性

    1.继承性 作用:子元素可以继承父元素的样式text-,font-,line-这些元素开头的都可以继承,以及color属性特殊性: ①. a标签的颜色不能继承,必须对a标签本身进行设置 ②. h标签的 ...