关于源码参考上次的搬运: 搬运openjdk8的sun.misc.Unsafe.java源码 `
小结: Unsafe的操作小结:
1. 分配内存
2. 数据、对象属性字段值的 set get update
3. 获取对象字段的偏移量(jdk中使用频繁)
4. CAS操作: CPU原子指令操作
5. 线程的挂起和恢复
6. 内存屏障
Unsafe类提供的操作有:
(1). 分配一个 bytes 个字节的内存空间
public native long allocateMemory(long bytes);
(2). 在内存 address 处重新分配 bytes个字节的内存
public native long reallocateMemory(long address, long bytes);
(3). 直接在内存中构造一个cls类的对象, 但不调用cls类的构造方法;
public native Object allocateInstance(Class<?> cls) throws InstantiationException;
(4). 处置从 allocateMemory
或 reallocateMemory
获得的内存块。 传递给此方法的 address
可以为null,在这种情况下,不采取任何措施。
public native void freeMemory(long address);
2. 数据、对象属性字段值的 set
get
update
直接通过内存地址,操作指定对象的属性
(1). 在指定对象或数组 o
上, 对偏移量 offset
处的属性的值 v
进行 加
操作, 增加的量为 delta
`
public final int getAndAddInt(Object o, long offset, int delta){...}
(2). 同上, offset所在字段的值为long
public final long getAndAddLong(Object o, long offset, long delta)
(3). 替换对象o的偏移量 offset处的 值, 不论旧的值是多少, 改为新的值 newValue
public final int getAndSetInt(Object o, long offset, int newValue)
(4). 同上, 修改的类型为long
public final long getAndSetLong(Object o, long offset, long newValue)
(5). 同上, 修改类型为引用对象
public final Object getAndSetObject(Object o, long offset, Object newValue)
get
获取 指定内存地址
上的指定类型的数据( address
)
获取 指定对象
的 偏移地址
上的指定类型的数据(Object o
, long offset
)
allocateMemory(long bytes)
是分配了 bytes 个字节的内存空间;
下面的get方法是 直接内存地址 address
上获取对应类型数据. 比如: getByte(address) 从内存 address取一个Byte类型的值;
public native byte getByte(long address); public native short getShort(long address); public native int getInt(long address); public native char getChar(long address); public native long getLong(long address); public native float getFloat(long address); public native double getDouble(long address); public native byte getByte(Object o, long offset); public native byte getByteVolatile(Object o, long offset); public native short getShort(Object o, long offset); public native short getShortVolatile(Object o, long offset); public native int getInt(Object o, long offset); public native int getIntVolatile(Object o, long offset); public native char getChar(Object o, long offset); public native char getCharVolatile(Object o, long offset); public native float getFloat(Object o, long offset); public native float getFloatVolatile(Object o, long offset); public native long getLong(Object o, long offset); public native long getLongVolatile(Object o, long offset); public native double getDouble(Object o, long offset); public native double getDoubleVolatile(Object o, long offset); public native boolean getBoolean(Object o, long offset); public native boolean getBooleanVolatile(Object o, long offset); // Object对象 public native Object getObject(Object o, long offset); public native Object getObjectVolatile(Object o, long offset);
设置 指定对象
的 偏移地址
上的指定类型的数据-( o
, offset
, x
)
设置 直接内存地址
上的指定类型的数据- address
public native void putByte(long address, byte x); public native void putByte(Object o, long offset, byte x); public native void putByteVolatile(Object o, long offset, byte x); // 省略....Short/Int/Char/Float/Long/Double/Boolean/Object](long address, x) // 省略....[Short/Int/Char/Float/Long/Double/Boolean/Object]Volatile(long address, x)
(1). 在当前对象中, 根据f字段获取对象的偏移量
(jdk中多处用到, 用来获取对象中声明的实例变量-使用变量名)
public native long objectFieldOffset(Field f);
例如: AtomicInteger中获取 value
再如: ConcurrentHashMap
(2).静态字段的上述同功能
public native Object staticFieldBase(Field f);
比较和交换给定的对象 o
偏移量 offset
处的 int
/ long
/ object
的值
public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x); public final native boolean compareAndSwapLong(Object o, long offset, long expected, long x); public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x); int x);
park
当前线程挂起 中断当前线程,直到满足以下条件之一返回:
(1). 当前线程被别的线程unpark
interrupted
(3). isAbsolute
true: 绝对时间, 而且, 绝对时间点
time已经过去;
(4). isAbsolute
false: 不是绝对时间, 纳秒时长
time 已经过去;
public native void park(boolean isAbsolute, long time);
unpark
恢复目标线程 对已经park了的目标线程解除阻塞. ( 若目标线程没有阻塞,则导致后续调用park不阻塞
。)
public native void unpark(Object thread);
loadFence() 表示该方法之前的所有load操作在内存屏障之前完成。
storeFence()表示该方法之前的所有store操作在内存屏障之前完成。
fullFence()表示该方法之前的所有load、store操作在内存屏障之前完成。
// Ensures lack of reordering of loads before the fence with loads or stores after the fence. public native void loadFence(); // Ensures lack of reordering of stores before the fence with loads or stores after the fence. public native void storeFence(); // Ensures lack of reordering of loads or stores before the fence with loads or stores after the fence. public native void fullFence();