J.U.C里常用到了Unsafe类资源汇总

Unsafe功能介绍:

1: 访问并并设置对象特定位置的值,即使值是private的,依然可以访问到

private static class Node<E> {
        volatile E item;
        volatile Node<E> next;

        private static final sun.misc.Unsafe UNSAFE;
        private static final long itemOffset;
        private static final long nextOffset;


        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class k = Node.class;
                itemOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("item"));
                nextOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("next")); //通过类反射机制用成员变量的名字获取取对应的field ,
                                                  //然后再通过field来获取field在class中的偏移量
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }


  注:java 类的反射机制是一种不安全且耗时的操作,如无必要请不要使用


 2:cas 操作,non-blocking算法(非阻塞算法)的基础 

    

    /**
     * Atomically update Java variable to <tt>x</tt> if it is currently
     * holding <tt>expected</tt>.
     * @return <tt>true</tt> if successful
     */
    public final native boolean compareAndSwapObject(Object o, long offset,
                                                     Object expected,
                                                     Object x);

    /**
     * Atomically update Java variable to <tt>x</tt> if it is currently
     * holding <tt>expected</tt>.
     * @return <tt>true</tt> if successful
     */
    public final native boolean compareAndSwapInt(Object o, long offset,
                                                  int expected,
                                                  int x);

CompareAndSwapInt在 jvm的内部实现:

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj);
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

Atomic::cmpxchg(x, addr, e)也是一个原子操作,通过比较缓存中的值与内存中的值是否相同来决定是否对其值进行更新

 通常的用法是将其包含在循环中:可参考java atomicInteger源码

    public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }


Unsafe功能调用实践:

 可参考:http://jackycheng2007.iteye.com/blog/1473464


如果相查看Unsafe源码:可以下载开源的openJDK源码,在目录openjdk/jdk/src/share/classes是所有的java api源码

在openjdk/jdk/src/share/classes/sun/misc下可以查看源码。大部分功能都是native 方法



参考:

 http://blog.csdn.net/aesop_wubo/article/details/7537278

未完...待续

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/congqingbin/article/details/17163753
文章标签: java api openjdk
个人分类: Java
上一篇logcat命令詳解
下一篇java类的延迟初始化及其特性
想对作者说点什么? 我来说一句

Java中Unsafe类详解

unsafe

bluetjs bluetjs

2016-10-08 16:49:55

阅读数:3678

没有更多推荐了,返回首页

关闭
关闭