关于Java Unsafe

来源:互联网 发布:微信点菜系统源码 编辑:程序博客网 时间:2024/06/07 07:46
最近看《Java并发编程的艺术》,其中多次提到Unsafe。很有意思的一个api,从名字上看很奇怪,并且不是公开的api,只有在JDK内部才能使用。查阅了一些资料:
http://www.cnblogs.com/mickole/articles/3757278.html
http://aswang.iteye.com/blog/1741871
http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
http://www.docjar.com/html/api/sun/misc/Unsafe.java.html
当然,搞Android的,少不了Android源代码:
libcore/libart/src/main/java/sun/misc/Unsafe.java

就几个我感兴趣的点研究一下:
(1)为什么叫unsafe?
http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/:
Java is a safe programming language and prevents programmer from doing a lot of stupid mistakes, most of which based on memory management. But, there is a way to do suchmistakes intentionally, usingUnsafe class.
Android源代码:
/**
 * The package name notwithstanding, this class is the quasi-standard
 * way for Java code to gain access to and use functionality which,
 * when unsupervised, would allow one to break the pointer/type safety
 * of Java.
 */
所谓Unsafe,即提供了一些API,可以绕过Java的安全机制(基于Java类型、引用、内存管理机制,对于内存访问的严格控制),进行一些更直接、更底层的操作,显然,在经典的Java编程风格中,这些操作是不安全的。这相当于Java的后门,所以只有JDK内部才能使用。
(2)原子api
Unsafe提供的一系列cas原子api,是JDK中原子操作类的实现基础。

http://www.docjar.com/html/api/sun/misc/Unsafe.java.html 注释中对此描述较清楚:

  858       /**  859        * Atomically update Java variable to <tt>x</tt> if it is currently  860        * holding <tt>expected</tt>.  861        * @return <tt>true</tt> if successful  862        */  863       public final native boolean compareAndSwapObject(Object o, long offset,  864                                                        Object expected,  865                                                        Object x);  866     867       /**  868        * Atomically update Java variable to <tt>x</tt> if it is currently  869        * holding <tt>expected</tt>.  870        * @return <tt>true</tt> if successful  871        */  872       public final native boolean compareAndSwapInt(Object o, long offset,  873                                                     int expected,  874                                                     int x);  875     876       /**  877        * Atomically update Java variable to <tt>x</tt> if it is currently  878        * holding <tt>expected</tt>.  879        * @return <tt>true</tt> if successful  880        */  881       public final native boolean compareAndSwapLong(Object o, long offset,  882                                                      long expected,  883                                                      long x);

(3)在安卓上如何实现的原子api?
以Unsafe.compareAndSwapInt()为例,追到native,一探究竟。

libcore/libart/src/main/java/sun/misc/Unsafe.java:

    /**     * Performs a compare-and-set operation on an <code>int</code>     * field within the given object.     *     * @param obj non-null; object containing the field     * @param offset offset to the field within <code>obj</code>     * @param expectedValue expected value of the field     * @param newValue new value to store in the field if the contents are     * as expected     * @return <code>true</code> if the new value was in fact stored, and     * <code>false</code> if not     */    public native boolean compareAndSwapInt(Object obj, long offset,            int expectedValue, int newValue);

显然,这是一个native method。在Android codebase中搜索native定义,发现了:

art/runtime/native/sun_misc_Unsafe.cc:

static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,                                         jint expectedValue, jint newValue) {  ScopedFastNativeObjectAccess soa(env);  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);  // JNI must use non transactional mode.  bool success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),                                                                    expectedValue, newValue);  return success ? JNI_TRUE : JNI_FALSE;}

调用了mirror::Object的CasFieldStrongSequentiallyConsistent32(),寻找定义:

art/runtime/mirror/object-inl.h:

template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>inline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,                                                           int32_t old_value, int32_t new_value) {  if (kCheckTransaction) {    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());  }  if (kTransactionActive) {    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);  }  if (kVerifyFlags & kVerifyThis) {    VerifyObject(this);  }  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);}

关键调用AtomicInteger的CompareExchangeStrongSequentiallyConsistent():

art/runtime/atomic.h:

  // Atomically replace the value with desired value if it matches the expected value.  // Participates in total ordering of atomic operations.  bool CompareExchangeStrongSequentiallyConsistent(T expected_value, T desired_value) {    return this->compare_exchange_strong(expected_value, desired_value, std::memory_order_seq_cst);  }

这段代码出现在类
template<typename T>
class PACKED(sizeof(T)) Atomic : public std::atomic<T>
可见,实际上使用的是std::atomic->compare_exchange_strong()

std::atomic有两个api:
compare_exchange_strong()
compare_exchange_weak()
api参考文档:
http://www.cplusplus.com/reference/atomic/atomic/compare_exchange_weak/
http://www.cplusplus.com/reference/atomic/atomic/compare_exchange_strong/
两个API基本功能是相同的
Compares the contents of the contained value with expected:
- if true, it replaces the contained value with val (like store).
- if false, it replaces expected with the contained value .
区别在于weak可能在满足true的情况下仍然返回false,所以只能在循环里使用,否则可以使用strong。之所以有weak版本是因为可以在某些平台上提升性能。





0 0
原创粉丝点击