java.util.concurrent 包下很多类的实现用到了基于硬件的CAS算法, 不再使用synchronized关键来进行并发控制,查看相关的源码后会发现最后都指向了一个类 ,这就是SUN未开源的sun.misc.Unsafe的类,该类功能很强大,涉及到类加载机制,其实例一般情况是获取不到的。还好有个反射的机制可以变通下,因为JVM 加载rt.jar时已经加载了该类,并且初始化过。上代码
/*
* Copyright 2010, the original author or authors. All rights reserved.
*/
package com.api;
import java.lang.reflect.Field;
import org.apache.log4j.Logger;
import sun.misc.Unsafe;
/**
* 获取{@link sun.misc.Unsafe}实例<br>
* 从rt.jar包中反编译该类获取的信息
*
* <pre>
*
* package sun.misc;
*
* import java.lang.reflect.Field;
* import java.lang.reflect.Modifier;
* import java.security.ProtectionDomain;
* import sun.reflect.Reflection;
*
* public final class Unsafe
* {
* private static final Unsafe theUnsafe;
* public static final int INVALID_FIELD_OFFSET = -1;
*
* private static native void registerNatives();
*
* public static Unsafe getUnsafe()
* {
* Class localClass = Reflection.getCallerClass(2);
* if (localClass.getClassLoader() != null)
* throw new SecurityException("Unsafe");
* return theUnsafe;
* }
* static
* {
* registerNatives();
*
* theUnsafe = new Unsafe();
* }
* ..........................
* </pre>
*
* @author <a href="mailto:xiao_jiang51@163.com">xiao jiang</a>
* @version %I%, %G%
* @history 2010-12-23
*/
public class UnsafeSupport {
private static Logger log = Logger.getLogger(UnsafeSupport.class);
private static Unsafe unsafe;
static {
Field field;
try {
// 由反编译Unsafe类获得的信息
field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
// 获取静态属性,Unsafe在启动JVM时随rt.jar装载
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
log.error("Get Unsafe instance occur error", e);
}
}
/**
* 获取{@link Unsafe }
*/
public static Unsafe getInstance() {
return unsafe;
}
public static void main(String[] args) {
}
}
搞个测试类玩玩
/*
* Copyright 2010, the original author or authors. All rights reserved.
*/
package com.api;
/**
* 分析目标
*
* @author <a href="mailto:xiao_jiang51@163.com">xiao jiang</a>
* @version %I%, %G%
* @history 2010-12-23
*/
public class AnalyzedTarget {
private byte byteParam;
private char charParam;
private short shorteParam;
private int intParam;
private int intParam2;
private long longParam;
private double doubleParam;
private String strParam;
private String strParam2;
}
运行测试案例
/*
*Copyright 2010, the original author or authors. All rights reserved.
*/
package com.api;
import java.lang.reflect.Field;
import org.apache.log4j.Logger;
import sun.misc.Unsafe;
/**
* 通过反射获取rt.jar下的Unsafe类
*
* @author <a href="mailto:xiao_jiang51@163.com">xiao jiang</a>
* @version %I%, %G%
* @history 2010-12-23
*/
public class UnsafeTest {
private static Logger log = Logger.getLogger(UnsafeTest.class);
public static void main(String[] args) {
Unsafe unsafe = UnsafeSupport.getInstance();
// 这个很牛
// unsafe.allocateMemory(1000000000l);
Class clazz = AnalyzedTarget.class;
Field[] fields = clazz.getDeclaredFields();
log.info("fieldName:fieldOffset");
// 获取属性偏移量,可以通过这个偏移量给属性设置
for (Field f : fields) {
log.info(f.getName() + ":" + unsafe.objectFieldOffset(f));
}
// arg0, arg1, arg2, arg3 分别是目标对象实例,目标对象属性偏移量,当前预期值,要设的值
// unsafe.compareAndSwapInt(arg0, arg1, arg2, arg3)
AnalyzedTarget target = new AnalyzedTarget();
// 偏移量编译后一般不会变的,intParam这个属性的偏移量
long intParamOffset = 24;
// 给它设置,返回true表明设置成功, 基于有名的CAS算法的方法,并发包用这个方法很多
log.info(unsafe.compareAndSwapInt(target, intParamOffset, 0, 3));
//比较失败
log.info(unsafe.compareAndSwapInt(target, intParamOffset, 0, 10));
//验证下上面是否设置成功,应该还是3,返回ture说明上面没该
log.info(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10));
}
}
结果
2010-12-23 16:59:56:352 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:29) - fieldName:fieldOffset
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - byteParam:36
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - charParam:32
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - shorteParam:34
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - intParam:24
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - intParam2:28
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - longParam:8
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - doubleParam:16
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - strParam:40
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:32) - strParam2:44
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:40) - true
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:42) - false
2010-12-23 16:59:56:368 [INFO] com.api.UnsafeTest.main(UnsafeTest.java:44) - true
注:j2sdk1.4.2_09 中compareAndSwapInt没提供,貌似1.5以上才有
bea的 jrockit81sp6_142_10中有,用到了jrockit.vm包中的Memory
分享到:
相关推荐
《深入解析JDK8中的sun.misc.UnSafe类》 在Java编程中,sun.misc.UnSafe类是一个非常特殊的存在。这个类在JDK8中扮演着一个核心的角色,它提供了对Java语言规范中未公开的底层操作的访问。尽管UnSafe类并非设计为...
2. **获取Unsafe实例** `Unsafe`类的设计是私有的单例,只能通过启动类加载器访问。通常的获取方式是通过反射来绕过权限检查: ```java Field f = Unsafe.class.getDeclaredField("theUnsafe"); f....
在早期版本中,MapDB 曾利用 `sun.misc.Unsafe` 类来优化内存管理和性能。`sun.misc.Unsafe` 是一个非常底层的 API,它允许 Java 程序员执行一些通常被认为是不安全或者不推荐的操作,如直接内存访问和对象字段的非...
例如,`sun.misc.Unsafe`类提供了许多非安全但高效的原生操作,如内存分配、原子操作等。尽管不推荐直接使用,但在高性能或低级别编程场景中,这些功能有时是必需的。 3. **编译器和JIT(Just-In-Time)优化**: ...
"大华视频监控java示例demo"是用于演示如何利用大华提供的SDK进行视频监控功能开发的实例代码。这些示例通常涵盖了设备连接、视频流获取、图像处理、报警事件处理等功能,让开发者快速理解如何与大华的监控设备进行...
Java中的`sun.misc.Unsafe`类是一个特殊的存在,它提供了对Java语言规范中未公开的底层操作的访问。自Java 1.4起,Unsafe就成为了一种强大的工具,允许开发人员执行一些Java语言不直接支持但又非常有用的任务。然而...
// 使用反射获取Unsafe实例 static Unsafe getUnsafe() { Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); return (Unsafe) field.get(null); } public ...
1. **实例化私有类**:通过反射获取`Unsafe`的实例,并使用`allocateInstance()`方法实例化私有构造器的类。这允许开发者绕过Java的正常构造器机制。 ```java Field f = Unsafe.class.getDeclaredField("theUnsafe...
这通常意味着应用代码无法直接通过getUnsafe()方法获取Unsafe实例。 但是,可以通过Java的反射机制绕过这个限制,具体做法是通过Unsafe类的DECLARE字段theUnsafe获取静态实例。尽管这样做可以绕过安全检查,但不...
首先,`Unsafe`类并不在Java标准API中公开,它位于`sun.misc`包下,这是一个非公开的包,通常用于内部实现。然而,由于其强大的功能,许多高性能的框架和库如Hadoop、Netty等都利用了`Unsafe`类来提高性能。在JDK ...
为了运行这个示例,需要在程序中初始化`Unsafe`实例,这通常通过反射访问`sun.misc.Unsafe`的私有字段`theUnsafe`实现: ```java private static final Unsafe unsafe; static { try { Field field = Unsafe....
在这个示例中,我们首先通过反射获取`Unsafe`实例,然后计算`state`字段的偏移量。`compareAndSwapInt`方法用于执行CAS操作,如果当前值等于预期值,那么原子地将值更新为新值。 尽管`Unsafe`类提供了强大的功能,...
1. **DirectByteBuffer的创建**:DirectByteBuffer可以通过`sun.misc.Unsafe`类的`allocateDirect()`方法或者`ByteBuffer.allocateDirect()`来创建。使用`allocateDirect()`方法时,不会在Java堆上创建任何对象,...
在Java编程语言中,Unsafe是一个特殊的类,它位于Java的标准类库之外,位于sun.misc包下。由于这个类的特殊性质,它没有被正式列入Java官方文档,但它提供了对Java虚拟机中底层操作的直接访问,允许开发者执行一些低...
使用Java的一个好处是你可以不用亲自来管理内存的分配和释放。当你用new关键字来实例化一个对象时,它所需的内存会自动的在Java堆中分配。堆会被垃圾回收器进行管理,并且它会在对象超出... sun.misc.Unsafe可以让你
`SizeOf`工具可能通过直接访问JVM的内部信息来实现这些计算,这可能涉及到使用反射(Reflection)或者特定于JVM的API,如Sun的`sun.misc.Unsafe`类,虽然这并不是标准的Java API,但在某些情况下能提供更底层的内存...
例如,`sun.misc.Unsafe`类(虽然非标准,但广泛使用)提供了访问内存的能力,包括获取对象大小。然而,需要注意的是,这个类在Java 9及以后的版本中被弃用,并且在某些JRE中可能不可用。 `SizeOfObject.java`可能...
6. **直接内存(线程共享)**:非JVM堆内存,通过`sun.misc.Unsafe`类可以直接访问。直接内存的使用可以提高性能,但可能导致内存溢出问题。 二、JVM执行子系统 1. **Class类文件结构**:Java源代码经过编译生成`....
Java使用垃圾回收机制自动管理内存,但仍然可以通过`sun.misc.Unsafe`类间接获取对象的内存地址。这个类不是公开API,但有时会被用来进行高性能的编程。 1. **直接内存访问(Direct Memory Access)** Java中的NIO...
- **Unsafe.allocateInstance**:在特定情况下,可以使用sun.misc.Unsafe类的allocateInstance()方法直接在堆上创建对象,但这通常是不推荐的,因为它绕过了常规的构造函数调用。 2. **对象的创建过程** 创建一个...