安全でありません
Unsafe
JDK基礎となるクラスライブラリはJavaメモリモデルにアクセスするための基礎となるメカニズムに基づいて、提供され、クラスのオブジェクトをインスタンス化することができ、ヒープメモリ(ダイレクトメモリ)、CASアトミック操作から直接操作。Javaベースの同期実装ツールのAQS、コンカレント・コンテナーは、ネッティー外部メモリヒープ操作は、クラスの実装に基づいています。
安全でないの取得の例
Unsafe
静的メソッドを提供しますgetUnsafe
に直接得ることができますUnsafe
オブジェクトが、この方法は、我々は通常の方法は、開発スロー呼び出すJDKのクラスライブラリの呼び出しを許可するSecurityException
例外を。もちろん、開発に、私たちはクラスのインスタンスを取得するためにリフレクションを使用することができます。このクラスは、プロパティ自体が含まれている
Unsafe theUnsafe
、あなたは、プロパティによって反射された後、最初の取得を取得することができUnsafe
インスタンス。
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
一般的な方法
/**
* 实例化一个类
* @param var1 要实例化类的Class对象
*/
public native Object allocateInstance(Class<?> var1) throws InstantiationException;
/**
* 获取一个类中某个属性的位移
* @param var1 属性的Field
*/
public native long objectFieldOffset(Field var1);
/**
* 获取某个实例对象的int属性值
* @param var1 实例对象
* @param var2 int属性的offset
*/
public native int getInt(Object var1, long var2);
/**
* 修改实例对象的int属性值
* @param var1 实例对象
* @param var2 int属性的offset
* @param var4 修改值
*/
public native void putInt(Object var1, long var2, int var4);
// 省略boolean、byte、char、short、float、double、long、Object
/**
* 申请堆外内存
* @param var1 申请内存大小,单位字节
* @return 堆外内存的起始地址
*/
public native long allocateMemory(long var1);
/**
* 释放堆外内存
* @param var1 堆外内存的起始地址
*/
public native void freeMemory(long var1);
/**
* CAS修改实例对象int属性值
* @param var1 实例对象
* @param var2 int属性值
* @param var4 int属性oldVal
* @param var5 int属性修改值newVal
*/
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
// 省略long、Object
/**
* 唤醒线程
* 具体使用可以参考 LockSupport.unpark()
*/
public native void unpark(Object var1);
/**
* 阻塞线程
* 具体使用可以参考 LockSupport.park()
*/
public native void park(boolean var1, long var2);
コード例
public class User {
private int age = 20;
public static void main(String[] args) {
// 构造器创建实例
User user = new User();
System.out.println(user);
// age = 20 表明使用构建器创建实例,会初始化实例属性
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
user.unsafeSetAge(1);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
user.setAge(2);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
// unsafe创建实例
user = User.getInstance();
System.out.println(user);
// age = 0 表明使用Unsafe创建实例,并不会初始化实例属性
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
user.unsafeSetAge(10);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
// 每次调用都会创建新的实例
user = User.getInstance();
System.out.println(user);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
user.unsafeSetAge(100);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
// cas修改
user.unsafeCas(100, 150);
System.out.println("unsafeGetAge : " + user.unsafeGetAge() + " userGetAge : " + user.getAge());
}
private static Unsafe UNSAFE;
private static long AGE_OFFSET;
static {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
UNSAFE = (Unsafe) f.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
try {
AGE_OFFSET = UNSAFE.objectFieldOffset(User.class.getDeclaredField("age"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public static User getInstance() {
try {
return (User)UNSAFE.allocateInstance(User.class);
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException("初始化User实例失败");
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int unsafeGetAge() {
return UNSAFE.getInt(this, AGE_OFFSET);
}
public void unsafeSetAge(int age) {
UNSAFE.putInt(this, AGE_OFFSET, age);
}
public void unsafeCas(int expectAge, int newAge) {
UNSAFE.compareAndSwapInt(this, AGE_OFFSET, expectAge, newAge);
}
@Override
public String toString() {
return "User{" +
"age=" + age + "," +
"hashcode=" + this.hashCode() +
'}';
}
}