Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率。但是,它是一把双刃剑:正如它的名字所预示的那样,它是 Unsafe的,它所分配的内存需要手动free(不被GC回收)。Unsafe类,提供了JNI某些功能的简单替代:确保高效性的同时,使事情变得更简 单。

这篇文章主要是以下文章的整理、翻译。

http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

1. Unsafe API的大部分方法都是native实现,它由105个方法组成,主要包括以下几类:

(1)Info相关。主要返回某些低级别的内存信息:addressSize(), pageSize()

(2)Objects相关。主要提供Object和它的域操纵方法:allocateInstance(),objectFieldOffset()

(3)Class相关。主要提供Class和它的静态域操纵方法:staticFieldOffset(),defineClass(),defineAnonymousClass(),ensureClassInitialized()

(4)Arrays相关。数组操纵方法:arrayBaseOffset(),arrayIndexScale()

(5)Synchronization相关。主要提供低级别同步原语(如基于CPU的CAS(Compare-And-Swap)原 语):monitorEnter(),tryMonitorEnter(),monitorExit(),compareAndSwapInt(),putOrderedInt()

(6)Memory相关。直接内存访问方法(绕过JVM堆直接操纵本地内存):allocateMemory(),copyMemory(),freeMemory(),getAddress(),getInt(),putInt()

 package com.yeepay.sxf.hashmaptest;

 import java.lang.reflect.Field;

 import sun.misc.Unsafe;

 public class TestUnSafe {

     public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
//获取属性
Field f=Unsafe.class.getDeclaredField("theUnsafe");
//
f.setAccessible(true);
//获取实例
Unsafe unsafe=(Unsafe) f.get(null); //实例化一个类
Player player=(Player) unsafe.allocateInstance(Player.class);
//打印年龄 打印结果:0
System.out.println("TestUnSafe.enclosing_method()"+player.getAge()); player.setAge(100); //打印结果100
System.out.println("TestUnSafe.main()"+player.getAge()); } } /**
* 普通类
* @author sxf
*
*/
class Player{
//年龄
private int age=12; //构造函数私有化
private Player(){
this.age=50;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

【一】
public native long objectFieldOffset(Field field);
==> 返回指定静态field的内存地址偏移量,在这个类的其他方法中这个值只是被用作一个访问
==>特定field的一个方式。这个值对于 给定的field是唯一的,并且后续对该方法的调用都应该返回相同的值

【二】
public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);
==>在obj的offset位置比较long field和期望的值,如果相同则更新。这个方法的操作应该是原子的,因此提供了一种不可中断的方式更新long field。成功返回true,不成功返回false
==>obj:包含要修改field的对象
==>offset:obj对象中long型field的偏移量
==>expect:希望field中存在的值
==>update:如果期望值expect与field的当前值相同,设置filed的值为这个新值

【三】
public native boolean compareAndSwapObject(Object obj, long offset, Object expect, Object update);
==>在obj的offset位置比较object field和期望的值,如果相同则更新。这个方法的操作应该是原子的,因此提供了一种不可中断的方式更新object field.成功返回true,不成功返回false
==>obj:包含要修改field的对象
==>offset:obj中object型field的偏移量
==>expect:希望field中存在的值
==>update:如果期望值expect与field的当前值相同,设置filed的值为这个新值

【四】
public native void putOrderedInt(Object obj, long offset, int value);
==>设置obj对象中offset偏移地址对应的整型field的值为指定值。这是一个有序或者有延迟的putIntVolatile方法,并且不保证值的改变被其他线程立即看到。只有在field被<code>volatile</code>修饰并且期望被意外修改的时候使用才有用。
==>obj:  包含要修改field的对象
==>offset:    <code>obj</code>中整型field的偏移量
==>value:   field将被设置的新值

【五】
 public native void putOrderedLong(Object obj, long offset, long value);
==>设置obj对象中offset偏移地址对应的long型field的值为指定值。这是一个有序或者有延迟的<code>putLongVolatile</cdoe>方法,并且不保证值的改变被其他线程立即看到。只有在field被<code>volatile</code>修饰并且期望被意外修改的时候使用才有用。
==>obj:包含需要修改field的对象
==>offset:<code>obj</code>中long型field的偏移量
==>value:field将被设置的新值

【六】
  public native void putOrderedObject(Object obj, long offset, Object value);
==>设置obj对象中offset偏移地址对应的整型field的值为指定值。支持volatile store语义
==>obj:包含需要修改field的对象
==>offset:<code>obj</code>中整型field的偏移量
==>value:field将被设置的新值

【七】
public native void putIntVolatile(Object obj, long offset, int value);
==>设置obj对象中offset偏移地址对应的整型field的值为指定值。支持volatile store语义
==>obj: 包含需要修改field的对象
==>offset:<code>obj</code>中整型field的偏移量
==>value:field将被设置的新值

【八】
 public native int getIntVolatile(Object obj, long offset);
==>获取obj对象中offset偏移地址对应的整型field的值,支持volatile load语义。
==>obj: 包含需要去读取的field的对象
==>offset:<code>obj</code>中整型field的偏移量

【九】
 public native void putLongVolatile(Object obj, long offset, long value);
==>设置obj对象中offset偏移地址对应的long型field的值为指定值。
==>obj:包含需要修改field的对象
==>offset: <code>obj</code>中long型field的偏移量
==>value: field将被设置的新值

【十】
public native long getLongVolatile(Object obj, long offset);
==>获取obj对象中offset偏移地址对应的long型field的值,支持volatile load语义。
==> obj:包含需要去读取的field的对象
==>offset:<code>obj</code>中long型field的偏移量

【十一】
public native void putLong(Object obj, long offset, long value);
==>设置obj对象中offset偏移地址对应的long型field的值为指定值。
==>obj:包含需要修改field的对象
==>offset: <code>obj</code>中long型field的偏移量
==>value:field将被设置的新值

【十二】
public native long getLong(Object obj, long offset);
==> 获取obj对象中offset偏移地址对应的long型field的值
==>obj:包含需要去读取的field的对象
==>offset:<code>obj</code>中long型field的偏移量

【十三】
 public native void putObjectVolatile(Object obj, long offset, Object value);
==> 设置obj对象中offset偏移地址对应的object型field的值为指定值。
==>obj:包含需要修改field的对象
==>offset:<code>obj</code>中object型field的偏移量
==>value:field将被设置的新值

【十四】
public native Object getObjectVolatile(Object obj, long offset);
==>获取obj对象中offset偏移地址对应的object型field的值,支持volatile load语义。
==>obj:包含需要去读取的field的对象
==>offset:  <code>obj</code>中object型field的偏移量

【十五】
  public native int arrayBaseOffset(Class arrayClass);
==>获取给定数组中第一个元素的偏移地址。 为了存取数组中的元素,这个偏移地址与<a href="#arrayIndexScale"><code>arrayIndexScale* </code></a>方法的非0返回值一起被使用
==>arrayClass:第一个元素地址被获取的class
==>返回:数组第一个元素 的偏移地址

【十六】
 public native int arrayIndexScale(Class arrayClass);
==>获取用户给定数组寻址的换算因子.一个合适的换算因子不能返回的时候(例如:基本类型), 返回0.这个返回值能够与<a href="#arrayBaseOffset"><code>arrayBaseOffset</code> </a>一起使用去存取这个数组class中的元素

【十七】
public native void unpark(Thread thread);
==>释放被<a href="#park"><code>park</code></a>创建的在一个线程上的阻塞.这个方法也可以被使用来终止一个先前调用<code>park</code>导致的阻塞.这个操作操作时不安全的,因此线程必须保证是活的.这是java代码不是native代码
==>thread:  要解除阻塞的线程

【十八】
public native void park(boolean isAbsolute, long time);
==>阻塞一个线程直到<a href="#unpark"><code>unpark</code></a>出现、线程被中断或者timeout时间到期。如果一个<code>unpark</code>调用已经出现了,这里只计数。timeout为0表示永不过期.当<code>isAbsolute</code>为true时,timeout是相对于新纪元之后的毫秒。否则这个值就是超时前的纳秒数。这个方法执行时也可能不合理地返回(没有具体原因)
==>isAbsolute:如果为true timeout的值是一个相对于新纪元之后的毫秒数
==>time:  可以是一个要等待的纳秒数,或者是一个相对于新纪元之后的毫秒数直到到达这个时间点

java编程之:Unsafe类的更多相关文章

  1. [深入浅出WP8.1(Runtime)]网络编程之HttpClient类

    12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...

  2. Java中的Unsafe类111

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

  3. 网络编程之HttpClient类(转)

    12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...

  4. Java安全之Unsafe类

    Java安全之Unsafe类 0x00 前言 前面使用到的一些JNI编程和Javaagent等技术,其实在安全里面的运用非常的有趣和微妙,这个已经说过很多次.后面还会发现一些比较有意思的技术,比如AS ...

  5. Java sun.misc.Unsafe类的学习笔记

    Java未开源的Unsafe类 Unsafe类可以为我们提供高效并且线程安全方式操作变量,直接和内存数据打交道. 获取Unsafe实体的方法 private static Unsafe getUnsa ...

  6. Java sun.misc.unsafe类

    Java是一个安全的开发工具,它阻止开发人员犯很多低级的错误,而大部份的错误都是基于内存管理方面的.如果你想搞破坏,可以使用Unsafe这个类.这个类是属于sun.*API中的类,并且它不是J2SE中 ...

  7. Java双刃剑之Unsafe类详解

    前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对Unsafe的态度都是 ...

  8. Java并发编程之ThreadLocal类

    ThreadLocal类可以理解为ThreadLocalVariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当 ...

  9. 并发编程之 Thread 类过期方法和常用方法

    前言 在 Java 刚诞生时,Thread 类就已经有了很多方法,但这些方法由于一些原因(有一些明显的bug或者设计不合理)有些已经废弃了,但是他们的方法名却是非常的好,真的是浪费.我们在进行并发必编 ...

随机推荐

  1. IP地址 子网掩码 默认网关 网络地址 广播地址

    “IP地址”是“TCP/IP”(Transmite Control Protocol 传输控制协议/Internet Protocol网际协议)里其中的一种协议. Internet之所以能将广阔范围内 ...

  2. 无线安全渗透测试套件WiFi-Pumpkin新版本发布

    WiFi-Pumpkin是一款无线安全检测工具,利用该工具可以伪造接入点完成中间人攻击,同时也支持一些其它的无线渗透功能.旨在提供更安全的无线网络服务,该工具可用来监听目标的流量数据,通过无线钓鱼的方 ...

  3. 什么php?

    PHP是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入HTML中使用.PHP的语法借鉴吸收了C语言.Java和Perl等流行计算机语言的特点,易于一般程序员学习.PHP的主要目标是允许网络开 ...

  4. UIWebView stringByEvaluatingJavaScriptFromString的使用方法

    stringByEvaluatingJavaScriptFromString 使用stringByEvaluatingJavaScriptFromString方法,需要等UIWebView中的页面加载 ...

  5. PHP输出缓冲控制

    说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会 向磁盘写入的,而是写到buffer中,当buffer写 ...

  6. 一个简单的tr:hover效果

    昨天,搞项目的时候,在一个小问题上卡了40分钟,现在想想,还是平时比较少去注意一些细节,经过这次,一定要去多注意细节了. 好了废话不多说,我现在说明下遇到的问题,一个表格中,要求是当鼠标滑过每一行时, ...

  7. Java可变参数/可变长参数

    Java可变参数/可变长参数 传递的参数不确定长度,是变长的参数,例如小例子: package demo; public class Demo { public static int sum(int ...

  8. ERROR 1130: Host ’...′ is not allowed to connect to this MySQL server

    /******************************************************************** * ERROR 1130: Host ’...′ is no ...

  9. LeetCode Subsets (DFS)

    题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. class Sol ...

  10. Oracle SQL语句追踪

    Oracle SQL语句追踪 1   SQL语句追踪 追踪SQL语句的执行过程需要在Oracle服务器端进行,Oracle服务器端会检测并记录访问进程所执行的所有SQL语句.下面使用的命令都是在命令行 ...