介绍
-
public native long objectFieldOffset方法:返回指定 的变量在所属类 中的内存偏移地址,
该偏移地址仅仅在该 Unsafe 函数中访 问指定宇段时使用 -
public native int arrayBaseOffset(Class<?> var1) 获取数组中第一个元素的地址
-
public native int arrayIndexScale(Class<?> var1) 获取数组中一个元素 占用的字节
-
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6)
比较对象 obj 中偏移量为 offset 的变量 的值是否与 expect 相等 , 相等则使用 update
值更新 , 然后返回 tru巳,否则返回 false -
public native long getLongVolatile(Object var1, long var2) 获取对象 obj 中偏移量为 offset 的变量对应 volatile i吾义的值
-
public native void putLongVolatile(Object var1, long var2, long var4) 设置 obj 对 象 中 offset偏移 的类型为 long 的 field 的值为 value,支持 volatile 语义
-
public native void putOrderedLong(Object var1, long var2, long var4) 置 obj 对象 中 offset偏移地址对应的 long 型 field 的值为 value 。 这是一个有延迟的 putLongvolatile 方法 ,并且不保证值修改对其他线程立刻可见 。 只有在变量使用 volatile 修饰并且预计会被意外修改时才使用 该方法
-
public native void park(boolean var1, long var2) 阻塞 当 前线程 , 其 中 参数 isAbsolute等于 false 且 time 等于 0 表示一直阻塞 。 time 大于 0 表示等待指定 的 time 后阻塞线
程会被唤醒 , 这个 time 是个相对值 , 是个增量值 , 也就是相对 当前时间 累加 time后当前线程就会被唤醒 。 如果 isAbsolute 等于 true , 并且 time 大于 0,则表示 阻塞
的 线程到 指定的 时 间点后会被唤醒,这里 time 是个绝对时间, 是将某个时间 点换算为 ms 后 的值 。 另 外,当其他线程调用 了 当 前阻塞线程 的 intemrrupt 方法而中断 了
当前线程 时-, 当 前线程也会返 回, 而 当其他线程调用 了 unPark 方法并且把 当 前线程作为参数时当前线程也会返回 -
public native void unpark(Object var1) 唤醒调用 park 后阻塞 的线程。
-
public final long getAndSetLong(Object var1, long var2, long var4) 获取对象 obj 中偏移
量为 offset 的变量 volatile i吾义的当前值 , 并设置变量 volatile i吾义的值为 update
public final long getAndSetLong(Object var1, long var2, long var4) {
long var6;
do {
//getLongvolatile 获取当前变量的值
var6 = this.getLongVolatile(var1, var2);
//使用CAS比较 CAS 原子操作设置新值 。这里使用 while 循环是考虑到,在多个线程 同时调用的情 况下 CAS 失败时需要重试
} while(!this.compareAndSwapLong(var1, var2, var6, var4));
return var6;
}
- long getAndAddLong(Object var1, long var2, long var4) 获取对象 。同 中偏移量为 offset 的变量 volatile i吾义的当前值 , 并设置变量值为原始值+addValue
public final long getAndAddLong(Object var1, long var2, long var4) {
long var6;
do {
//getLongvolatile 获取当前变量的值
var6 = this.getLongVolatile(var1, var2);
//进行 CAS 操作时使用了原始值+传递的增量参数 addValue 的值
} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));
return var6;
}
简单使用
package com.ghgcn.threadstudy.lesson01;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* @author 刘楠
* @since 2019/7/1
*/
public class TestUnSafe1 {
private static Unsafe unsafe;
private static long stateOffset;
private volatile long state=0;
static {
try {
//通过反射获取Unsafe的成员变量theUnsafe
Field field = Unsafe.class.getDeclaredField("theUnsafe");
//设置为内存可以取
field.setAccessible(true);
//获取值
unsafe=(Unsafe)field.get(null);
//获取偏移量
stateOffset=unsafe.objectFieldOffset(TestUnSafe1.class.getDeclaredField("state"));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
System.err.println(e.getLocalizedMessage());
}
}
public static void main(String[] args) {
TestUnSafe1 testUnSafe1 = new TestUnSafe1();
boolean success = unsafe.compareAndSwapLong(testUnSafe1, stateOffset, 0, 2);
System.out.println("success "+success);
}
}