Java JDK Unsafe
最近看java.util.concurrent.atomic包,发现其中大量的用到Unsafe这个类。就在网上查了一下这个类到底是来干嘛的.java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,主要提供了以下功能:
1、内存操作
类中提供的3个本地方法allocateMemory、reallocateMemory、freeMemory分别用于分配内存,扩充内存和释放内存,与C语言中的3个方法对应.
/** 分配内存 */
public native long allocateMemory(long l);
/** 扩充内存 */
public native long reallocateMemory(long l, long l1);
/** 释放内存 */
public native void freeMemory(long l);
2、字段的定位与修改
可以定位对象某字段的内存位置,也可以修改对象的字段值,即使它是私有的;
字段的定位:
JAVA中对象的字段的定位可能通过staticFieldOffset方法实现,该方法返回给定field的内存地址偏移量,这个值对于给定的filed是唯一的且是固定不变的。
getIntVolatile方法获取对象中offset偏移地址对应的整型field的值,支持volatile load语义。
getLong方法获取对象中offset偏移地址对应的long型field的值。
数组元素定位:
1. Unsafe类中有很多以BASE_OFFSET结尾的常量,比如ARRAY_INT_BASE_OFFSET,ARRAY_BYTE_BASE_OFFSET等,这些常量值是通过arrayBaseOffset()方法得到的.arrayBaseOffset()方法是一个本地方法,可以获取数组第一个元素的偏移地址.
2. Unsafe类中还有很多以INDEX_SCALE结尾的常量,比如 ARRAY_INT__SCALE,
ARRAY_BYTE_INDEX_SCALE等,这些常量值是通过方法得到的.arrayIndexScale方法也是一个本地方法,可以获取数组的转换因子,也就是数组中元素的增量地址.
结论:
将arrayBaseOffset与arrayIndexScale配合使用,可以定位数组中每个元素在内存中的位置。
public final class Unsafe {public static final int ARRAY_INT_BASE_OFFSET;public static final int ARRAY_INT_INDEX_SCALE;public native long staticFieldOffset(Field field);public native int getIntVolatile(Object obj, long l);public native long getLong(Object obj, long l);public native int arrayBaseOffset(Class class1);public native int arrayIndexScale(Class class1);static {ARRAY_INT_BASE_OFFSET = theUnsafe.arrayBaseOffset([I);ARRAY_INT_INDEX_SCALE = theUnsafe.arrayIndexScale([I);}
}
下面这个例子演示了简单的修改一个byte[]的数据。
这个例子在eclipse里不能直接编译,要到项目的属性,Java Compiler,Errors/Warnings中Forbidden reference(access rules)中设置为warning。
另外,因为sun.misc.Unsafe包不能直接使用,所有代码里用反射的技巧得到了一个Unsafe的实例。
public class Test {private static int byteArrayBaseOffset;public static void main(String[] args) throws SecurityException,NoSuchFieldException, IllegalArgumentException,IllegalAccessException {Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);Unsafe UNSAFE = (Unsafe) theUnsafe.get(null);System.out.println(UNSAFE);byte[] data = new byte[10];System.out.println(Arrays.toString(data));byteArrayBaseOffset = UNSAFE.arrayBaseOffset(byte[].class);System.out.println(byteArrayBaseOffset);UNSAFE.putByte(data, byteArrayBaseOffset, (byte) 1);UNSAFE.putByte(data, byteArrayBaseOffset + 5, (byte) 5);System.out.println(Arrays.toString(data));}
}
运行结果:
sun.misc.Unsafe@6af62373
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
24
[1, 0, 0, 0, 0, 5, 0, 0, 0, 0]
3、挂起与恢复
将一个线程进行挂起是通过park方法实现的,调用 park后,线程将一直阻塞直到超时或者中断等条件出现。unpark可以终止一个挂起的线程,使其恢复正常。整个并发框架中对线程的挂起操作被封装在 LockSupport类中,LockSupport类中有各种版本pack方法,但最终都调用了Unsafe.park()方法。
public class LockSupport {public static void unpark(Thread thread) {if (thread != null)unsafe.unpark(thread);}public static void park(Object blocker) {Thread t = Thread.currentThread();setBlocker(t, blocker);unsafe.park(false, 0L);setBlocker(t, null);}public static void parkNanos(Object blocker, long nanos) {if (nanos > 0) {Thread t = Thread.currentThread();setBlocker(t, blocker);unsafe.park(false, nanos);setBlocker(t, null);}}public static void parkUntil(Object blocker, long deadline) {Thread t = Thread.currentThread();setBlocker(t, blocker);unsafe.park(true, deadline);setBlocker(t, null);}public static void park() {unsafe.park(false, 0L);}public static void parkNanos(long nanos) {if (nanos > 0)unsafe.park(false, nanos);}public static void parkUntil(long deadline) {unsafe.park(true, deadline);}
}
4、CAS操作(乐观锁)
首先介绍一下什么是Compare And Swap(CAS)?简单的说就是比较并交换。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。” Java并发包(java.util.concurrent)中大量使用了CAS操作,涉及到并发的地方都调用了sun.misc.Unsafe类方法进行CAS操作。
在Unsafe中是通过compareAndSwapXXX方法实现的。
/**
* 比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的。
*
* @param obj 需要更新的对象
* @param offset obj中整型field的偏移量
* @param expect 希望field中存在的值
* @param update 如果期望值expect与field的当前值相同,设置filed的值为这个新值
* @return 如果field的值被更改返回true
*/
public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);
转载地址:
源码剖析之sun.misc.Unsafe
Java中Unsafe类详解
JAVA并发编程学习笔记之Unsafe类
Java JDK Unsafe相关推荐
- JDK Unsafe类的使用与CAS原子特性
JDK Unsafe类的使用与CAS原子特性 Java.util.concurrent.atomic包,其中包含了大量使用到Unsafe这个类 Java不能直接访问操作系统的底层,而是通过本地方法来访 ...
- java jdk 1.8 安装_下载、安装、配置 java jdk1.8
近期配置react native的开发环境,所以就从配置环境开始.rn的环境配置有那么几项,其中重要的一个就是java jdk(Java Development Kit 的缩写),那么以下就是下载.安 ...
- Linux(Centos)之安装Java JDK及注意事项
1.准备工作 a.因为Java JDK区分32位和64位系统,所以在安装之前必须先要判断以下我们的Centos系统为多少位系统,命令如下: uname -a 解释:如果有x86_64就是64位的,没有 ...
- Java JDK 11:现在可以使用所有新功能
为什么80%的码农都做不了架构师?>>> 删除了CORBA,Java EE和JavaFX支持,但添加了十几个主要新功能 目录 哪里可以下载JDK 11 Java 11 JDK中 ...
- ubuntu14.04配置java jdk
1.下载JDK 目前最新的JDK版本是: Java SE Development Kit 8u51 下载地址:http://www.oracle.com/technetwork/java/javase ...
- java jdk下载过慢 解决方案
下载JDK的时候,10k每秒的速度简直难以忍受,下面列出了一些解决方法 可用的加速方法 将下载链接去掉https 由于下载时默认是https,所以会慢一些,使用http之后虽然还是慢,但是也能稳定在4 ...
- mac java jdk_mac下java JDK的下载安装和配置
1.首先在Java SE Development Kit 8这个地址下下载如图的.dmg文件 这个是jdk1.8版本,当然你也可以选择其它版本. 2.下载并默认安装后,在电脑资源文件夹下找到java, ...
- Java jdk 安装笔记
1,下载http://download.oracle.com/otn-pub/java/jdk/7u9-b05/jdk-7u9-linux-i586.tar.gz 2,解压 tar -zxvf jdk ...
- kali 安装java jdk
先卸载原有java版本 kali自带的java版本为 Openjdk sudo apt-get remove openjdk* 卸载不需要的java软件 sudo apt autoremove 解压到 ...
最新文章
- Python之路--WEB框架本质
- TOJ_1003题解
- 2014年江苏省计算机二级c语言考试大纲,2009年江苏省计算机等级考试二级C语言考试大纲...
- html中设置td中内容的垂直位置
- mysql数据中文乱码_win10 系统解决mysql中文乱码问题
- SQL Server表结构和数据导入到MySQL
- 前端学习(1351)模板引擎
- ctf的php,CTF中常见的PHP漏洞
- PyOpenGL之3D界面详解(二)
- 【英语学习】【English L06】U03 House L6 Sharing an apartment
- 【设计模式】第七章 享元模式
- oracle 存储过程 存储 blob,穿越oracle存储过程的Blob参数上传文件
- 医学图像分析相关的会议
- 虹软2.0 离线人脸识别 Android 开发 Demo
- JSP页面中taglib的uri设置
- web安全:sql 注入
- 中兴新支点操作系统挺好用的,国内电脑应预装国产操作系统
- C语言处理中文字符,C语言中关于汉字的处理
- 解决 nvcc: command not found
- 数据安全与隐私保护要点整理
热门文章
- Java基础—break label 带标签的break语句的用法。
- python的标志为什么是蛇_Guido给Python语言起名的原因是他家有只宠物蛇
- CorelDRAW易拉宝设计
- JavaScript笔记之一:JS原生
- Mini LED电视大热,“智能化”渐行渐远?
- 又好气又好笑(语录)
- java三目运算符(三元运算符)
- 请教!rabbitMQ怎么确认同一个队列所有消费者收到消息?
- 华为p40手机自带计算机,华为P40自带哪些应用?
- 摄像头人数统计解决方案:Camlytics 2.2.8 Crack