Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使得Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。

创新互联-专业网站定制、快速模板网站建设、高性价比潼关网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式潼关网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖潼关地区。费用合理售后完善,十载实体公司更值得信赖。
java.util.concurrent.atomic包下的原子操作类,基本都是使用Unsafe实现的。
Unsafe提供的API大致可分为内存操作、CAS、Class、对象操作、线程、系统信息获取、内存屏障、数组操作等几类。
java.util.concurrent.atomic包中的原子类基本都用的Unsafe
- private static final Unsafe unsafe = Unsafe.getUnsafe();
 - private static final long valueOffset;
 - static {
 - try {
 - valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
 - } catch (Exception ex) { throw new Error(ex); }
 - }
 - public final int getAndSet(int newValue) {
 - return unsafe.getAndSetInt(this, valueOffset, newValue);
 - }
 
LockSupport类中有应用unpark,park
- public static void park(Object blocker) {
 - Thread t = Thread.currentThread();
 - setBlocker(t, blocker);
 - UNSAFE.park(false, 0L);
 - setBlocker(t, null);
 - }
 
- public static void unpark(Thread thread) {
 - if (thread != null)
 - UNSAFE.unpark(thread);
 - }
 
loadFence:保证在这个屏障之前的所有读操作都已经完成。
storeFence:保证在这个屏障之前的所有写操作都已经完成。
fullFence:保证在这个屏障之前的所有读写操作都已经完成。
在java8中 有这个StampedLock类,该类中应用了内存屏障功能。
- private static final sun.misc.Unsafe U;
 - static {
 - try {
 - U = sun.misc.Unsafe.getUnsafe();
 - } catch (Exception e) {
 - throw new Error(e);
 - }
 - }
 - public boolean validate(long stamp) {
 - U.loadFence();
 - return (stamp & SBITS) == (state & SBITS);
 - }
 
- U.loadFence();
 
Unsafe.java
- public final class Unsafe {
 - private static native void registerNatives();
 - static {
 - registerNatives();
 - sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
 - }
 - private Unsafe() {}
 - private static final Unsafe theUnsafe = new Unsafe();
 - // ...
 - }
 
Unsafe类是final且是单例的,并且theUnsafe字段是private;通过如下方法获取实例
方法1
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;
 - theUnsafe.setAccessible(true) ;
 - Unsafe unsafe = (Unsafe) theUnsafe.get(null) ;
 
方法2
- private static Unsafe unsafe = null ;
 - static {
 - try {
 - Constructor
 cons = Unsafe.class.getDeclaredConstructor() ; - cons.setAccessible(true) ;
 - unsafe = cons.newInstance() ;
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 
- int i = 0 ;
 - public static void main(String[] args) throws Exception {
 - UnsafeDemo d = new UnsafeDemo() ;
 - // 获取Unsafe实例
 - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;
 - theUnsafe.setAccessible(true) ;
 - Unsafe unsafe = (Unsafe) theUnsafe.get(null) ;
 - // 获取类的实例变量
 - Field f = UnsafeDemo.class.getDeclaredField("i") ;
 - // 获取字段相对Java对象的"起始地址"的偏移量
 - long fieldOffset = unsafe.objectFieldOffset(f) ;
 - System.out.println(fieldOffset) ;
 - // 设置值
 - boolean success = unsafe.compareAndSwapInt(d, fieldOffset, 0, 10) ;
 - System.out.println(success) ;
 - System.out.println(d.i) ;
 - }
 
- private static Unsafe unsafe = null ;
 - static {
 - try {
 - Constructor
 cons = Unsafe.class.getDeclaredConstructor() ; - cons.setAccessible(true) ;
 - unsafe = cons.newInstance() ;
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 - public static void allocate() {
 - try {
 - Person p = (Person)unsafe.allocateInstance(Person.class) ;
 - p.setId("s001");
 - System.out.println(p.getValue()) ;
 - System.out.println(p.getId()) ;
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 
执行结果:
- private Person p = new Person("1", "张三") ;
 - public static void main(String[] args) throws Exception {
 - UnSafeObjectDemo d = new UnSafeObjectDemo() ;
 - Field field = Unsafe.class.getDeclaredField("theUnsafe") ;
 - field.setAccessible(true) ;
 - Unsafe unsafe = (Unsafe) field.get(null) ;
 - Field f = d.getClass().getDeclaredField("p") ;
 - long offset = unsafe.objectFieldOffset(f) ;
 - System.out.println(offset) ;
 - boolean res = unsafe.compareAndSwapObject(d, offset, d.p, new Person("2", "李四")) ;
 - System.out.println(res) ;
 - System.out.println(d.p.getName()) ;
 - }
 
当不知道即将使用的对象有何构造函数,或是不想使用现有对象的构造函数创建对象时,可以通过如下方式:
- Constructor
 cons = (Constructor ) ReflectionFactory.getReflectionFactory().newConstructorForSerialization(Teacher.class, - Object.class.getConstructor());
 - cons.setAccessible(true);
 - Teacher t = cons.newInstance() ;
 - System.out.println(t) ;
 
- public class AtomicCount {
 - private static Unsafe unsafe ;
 - private int value ;
 - private static long valueOffset ;
 - static {
 - try {
 - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;
 - theUnsafe.setAccessible(true) ;
 - unsafe = (Unsafe) theUnsafe.get(null) ;
 - Field f = AtomicCount.class.getDeclaredField("value") ;
 - valueOffset = unsafe.objectFieldOffset(f) ;
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 - public AtomicCount(int value) {
 - this.value = value ;
 - }
 - public final int get() {
 - return value;
 - }
 - public final int getAndIncrement() {
 - return unsafe.getAndAddInt(this, valueOffset, 1);
 - }
 - }
 
完毕!!!
Copyright © 2009-2022 www.wtcwzsj.com 青羊区广皓图文设计工作室(个体工商户) 版权所有 蜀ICP备19037934号