[并发J.U.C]---简单理解Unsafe
2018-11-28 本文已影响0人
nicktming
前言
由于并发包中很多数据结构的底层实现都是依赖于
CAS
,CAS
也就是用Unsafe
实现.CAS
操作有3
个操作数, 内存位置, 预期原值, 和 新值, 如果内存位置的值与预期原值相等,则在该内存位置填写新的值, 否则不修改原值.
本文源码: 源码下载
例子
先通过一个简单的例子了解一下
Unsafe
的操作.
package com.usafe;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class TestField {
private int age;
private String name;
private static int value;
public static void main(String[] args) throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
long setoff = unsafe.objectFieldOffset(TestField.class.getDeclaredField("age"));
System.out.println("setoff:" + setoff);
TestField test1 = new TestField();
test1.age = 10;
TestField test2 = new TestField();
test2.age = 10;
unsafe.compareAndSwapInt(test1, setoff, 10, 11);
unsafe.compareAndSwapInt(test2, setoff, 10, 12);
System.out.println("test1 age:" + test1.age);
System.out.println("test2 age:" + test2.age);
}
}
输出如下, 从输出结果可以看到通过
objectFieldOffset
方法可以得到该成员变量在类TestField
中的偏移量, 在方法compareAndSwapInt
中第一个变量是类对象, 和第二个变量是偏移量即可得到该变量在内存中真正的位置, 然后进行CAS
操作.
setoff:12
test1 age:11
test2 age:12
Unsafe方法
以下只是
Unsafe
的一些方法,基本上看到方法名字就可以知道大概什么作用,可以自己尝试一下, 由于本文是为其他文章做铺垫, 因此就不对其源码(C++实现
)进行分析.
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
public native Object getObjectVolatile(Object var1, long var2);
public native void putObjectVolatile(Object var1, long var2, Object var4);
public native int getIntVolatile(Object var1, long var2);
public native void putIntVolatile(Object var1, long var2, int var4);
public native boolean getBooleanVolatile(Object var1, long var2);
public native void putBooleanVolatile(Object var1, long var2, boolean var4);
public native byte getByteVolatile(Object var1, long var2);
public native void putByteVolatile(Object var1, long var2, byte var4);
public native short getShortVolatile(Object var1, long var2);
public native void putShortVolatile(Object var1, long var2, short var4);
public native char getCharVolatile(Object var1, long var2);
public native void putCharVolatile(Object var1, long var2, char var4);
public native long getLongVolatile(Object var1, long var2);
public native void putLongVolatile(Object var1, long var2, long var4);
public native float getFloatVolatile(Object var1, long var2);
public native void putFloatVolatile(Object var1, long var2, float var4);
public native double getDoubleVolatile(Object var1, long var2);
public native void putDoubleVolatile(Object var1, long var2, double var4);
public native void putOrderedObject(Object var1, long var2, Object var4);
public native void putOrderedInt(Object var1, long var2, int var4);
public native void putOrderedLong(Object var1, long var2, long var4);
public native void unpark(Object var1);
public native void park(boolean var1, long var2);