关于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, using
Unsafe
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.
*/
* 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,一探究竟。
/** * 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定义,发现了:
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(),寻找定义:
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():
// 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>
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版本是因为可以在某些平台上提升性能。- if true, it replaces the contained value with val (like store).
- if false, it replaces expected with the contained value .
0 0
- 关于Java Unsafe
- Java --- Unsafe
- JAVA-Unsafe
- Java Unsafe
- 关于使用Unsafe code
- Unsafe--Java中Unsafe类详解
- java 中的Unsafe
- Java中Unsafe类
- java 中的Unsafe
- java 中的Unsafe(转)
- Java。UnSafe类
- java 中的Unsafe
- java 中的Unsafe
- java 中的Unsafe
- Java sun.misc.Unsafe
- Java Unsafe 类
- Java JDK Unsafe
- java中的Unsafe
- 什么是异 常
- 数独
- 【北邮OJ】88. 最值问题
- 一些常用的数学符号
- c语言实现快速排序
- 关于Java Unsafe
- C#入门 自用笔记 9*9算术表的生成。
- 机器学习(周志华 )-2模型评估与选择
- RDC 表达式
- 关于ajax的学习笔记(心得)
- 121. 122.123 Best Time to Buy and Sell Stock
- LDS文件格式分析
- 德国CeBIT 2017,数字冰雹开启智慧城市决策新视角
- 淘淘商城第二天