【源码】Unsafe
sun.misc.Unsafe
package sun.misc;
import java.security.*;
import java.lang.reflect.*;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
//看注释,一组执行底层,不安全操作的方法。
/**
* A collection of methods for performing low-level, unsafe operations.
* Although the class and all methods are public, use of this class is
* limited because only trusted code can obtain instances of it.
*
* @author John R. Rose
* @see #getUnsafe
*/
public final class Unsafe {
//注册本地方法
private static native void registerNatives();
static {
registerNatives();
sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
}
//不能通过new Unsafe()来实例化。
private Unsafe() {}
//单例
private static final Unsafe theUnsafe = new Unsafe();
/**
* 此方法被限制只有Bootstrap Class Loader加载的类才能调用,要不然会抛出SecurityException异常。
*
* 1.可以通过反射来获取Unsafe实例。
* Unsafe.class.getDeclaredField("theUnsafe");
* f.setAccessible(true);
* Unsafe unsafe = (Unsafe) f.get(null);
*
* 2.可以令使用到Unsafe的类授信
* java -Xbootclasspath: com.local.test.xxx
*/
@CallerSensitive
public static Unsafe getUnsafe() {
Class<?> caller = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(caller.getClassLoader()))
throw new SecurityException("Unsafe");
return theUnsafe;
}
//通过对象偏移量获取值(这个值可以是8大基本类型,也可以是引用类型)。
//设置对象偏移量的值(这个值可以是8大基本类型,也可以是引用类型)。
//每个类型都有独自的上述两种本地方法。
public native int getInt(Object o, long offset);
public native void putInt(Object o, long offset, int x);
public native Object getObject(Object o, long offset);
public native void putObject(Object o, long offset, Object x);
public native boolean getBoolean(Object o, long offset);
public native void putBoolean(Object o, long offset, boolean x);
public native byte getByte(Object o, long offset);
public native void putByte(Object o, long offset, byte x);
public native short getShort(Object o, long offset);
public native void putShort(Object o, long offset, short x);
public native char getChar(Object o, long offset);
public native void putChar(Object o, long offset, char x);
public native long getLong(Object o, long offset);
public native void putLong(Object o, long offset, long x);
public native float getFloat(Object o, long offset);
public native void putFloat(Object o, long offset, float x);
public native double getDouble(Object o, long offset);
public native void putDouble(Object o, long offset, double x);
@Deprecated
public int getInt(Object o, int offset) {
return getInt(o, (long)offset);
}
@Deprecated
public void putInt(Object o, int offset, int x) {
putInt(o, (long)offset, x);
}
@Deprecated
public Object getObject(Object o, int offset) {
return getObject(o, (long)offset);
}
@Deprecated
public void putObject(Object o, int offset, Object x) {
putObject(o, (long)offset, x);
}
@Deprecated
public boolean getBoolean(Object o, int offset) {
return getBoolean(o, (long)offset);
}
@Deprecated
public void putBoolean(Object o, int offset, boolean x) {
putBoolean(o, (long)offset, x);
}
@Deprecated
public byte getByte(Object o, int offset) {
return getByte(o, (long)offset);
}
@Deprecated
public void putByte(Object o, int offset, byte x) {
putByte(o, (long)offset, x);
}
@Deprecated
public short getShort(Object o, int offset) {
return getShort(o, (long)offset);
}
@Deprecated
public void putShort(Object o, int offset, short x) {
putShort(o, (long)offset, x);
}
@Deprecated
public char getChar(Object o, int offset) {
return getChar(o, (long)offset);
}
@Deprecated
public void putChar(Object o, int offset, char x) {
putChar(o, (long)offset, x);
}
@Deprecated
public long getLong(Object o, int offset) {
return getLong(o, (long)offset);
}
@Deprecated
public void putLong(Object o, int offset, long x) {
putLong(o, (long)offset, x);
}
@Deprecated
public float getFloat(Object o, int offset) {
return getFloat(o, (long)offset);
}
@Deprecated
public void putFloat(Object o, int offset, float x) {
putFloat(o, (long)offset, x);
}
@Deprecated
public double getDouble(Object o, int offset) {
return getDouble(o, (long)offset);
}
@Deprecated
public void putDouble(Object o, int offset, double x) {
putDouble(o, (long)offset, x);
}
//获取给定地址的值(这个值可以是8大基本类型,也可以是引用类型)。
//设置给定地址上的值(这个值可以是8大基本类型,也可以是引用类型)。
//每个类型都有独自的上述两种本地方法。
public native byte getByte(long address);
public native void putByte(long address, byte x);
public native short getShort(long address);
public native void putShort(long address, short x);
public native char getChar(long address);
public native void putChar(long address, char x);
public native int getInt(long address);
public native void putInt(long address, int x);
public native long getLong(long address);
public native void putLong(long address, long x);
public native float getFloat(long address);
public native void putFloat(long address, float x);
public native double getDouble(long address);
public native void putDouble(long address, double x);
//获取给定地址的本地指针
//设置给定地址的本地指针
public native long getAddress(long address);
public native void putAddress(long address, long x);
/// wrappers for malloc, realloc, free:
//分配内存
public native long allocateMemory(long bytes);
//重新分配内存
public native long reallocateMemory(long address, long bytes);
//初始化内存内容
public native void setMemory(Object o, long offset, long bytes, byte value);
public void setMemory(long address, long bytes, byte value) {
setMemory(null, address, bytes, value);
}
//拷贝内存内容
public native void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes);
public void copyMemory(long srcAddress, long destAddress, long bytes) {
copyMemory(null, srcAddress, null, destAddress, bytes);
}
//释放内存
public native void freeMemory(long address);
/// random queries
/**
* This constant differs from all results that will ever be returned from
* {@link #staticFieldOffset}, {@link #objectFieldOffset},
* or {@link #arrayBaseOffset}.
*/
public static final int INVALID_FIELD_OFFSET = -1;
@Deprecated
public int fieldOffset(Field f) {
if (Modifier.isStatic(f.getModifiers()))
return (int) staticFieldOffset(f);
else
return (int) objectFieldOffset(f);
}
@Deprecated
public Object staticFieldBase(Class<?> c) {
Field[] fields = c.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (Modifier.isStatic(fields[i].getModifiers())) {
return staticFieldBase(fields[i]);
}
}
return null;
}
//获取静态属性偏移量
public native long staticFieldOffset(Field f);
//获取对象字段的偏移量
public native long objectFieldOffset(Field f);
//返回静态属性的位置,实际上这个方法返回的是一个快照,有可能返回null,它是一个‘cookie’而不是一个对象。
public native Object staticFieldBase(Field f);
//检查给定的class是否需要初始化
public native boolean shouldBeInitialized(Class<?> c);
//检查给定的class是否已经初始化
public native void ensureClassInitialized(Class<?> c);
//返回数组第一个元素的偏移量
public native int arrayBaseOffset(Class<?> arrayClass);
public static final int ARRAY_BOOLEAN_BASE_OFFSET
= theUnsafe.arrayBaseOffset(boolean[].class);
public static final int ARRAY_BYTE_BASE_OFFSET
= theUnsafe.arrayBaseOffset(byte[].class);
public static final int ARRAY_SHORT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(short[].class);
public static final int ARRAY_CHAR_BASE_OFFSET
= theUnsafe.arrayBaseOffset(char[].class);
public static final int ARRAY_INT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(int[].class);
public static final int ARRAY_LONG_BASE_OFFSET
= theUnsafe.arrayBaseOffset(long[].class);
public static final int ARRAY_FLOAT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(float[].class);
public static final int ARRAY_DOUBLE_BASE_OFFSET
= theUnsafe.arrayBaseOffset(double[].class);
public static final int ARRAY_OBJECT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(Object[].class);
//返回数组中元素的偏移量
public native int arrayIndexScale(Class<?> arrayClass);
public static final int ARRAY_BOOLEAN_INDEX_SCALE
= theUnsafe.arrayIndexScale(boolean[].class);
public static final int ARRAY_BYTE_INDEX_SCALE
= theUnsafe.arrayIndexScale(byte[].class);
public static final int ARRAY_SHORT_INDEX_SCALE
= theUnsafe.arrayIndexScale(short[].class);
public static final int ARRAY_CHAR_INDEX_SCALE
= theUnsafe.arrayIndexScale(char[].class);
public static final int ARRAY_INT_INDEX_SCALE
= theUnsafe.arrayIndexScale(int[].class);
public static final int ARRAY_LONG_INDEX_SCALE
= theUnsafe.arrayIndexScale(long[].class);
public static final int ARRAY_FLOAT_INDEX_SCALE
= theUnsafe.arrayIndexScale(float[].class);
public static final int ARRAY_DOUBLE_INDEX_SCALE
= theUnsafe.arrayIndexScale(double[].class);
public static final int ARRAY_OBJECT_INDEX_SCALE
= theUnsafe.arrayIndexScale(Object[].class);
//获取本地指针大小(byte),通常为4or8
public native int addressSize();
public static final int ADDRESS_SIZE = theUnsafe.addressSize();
//获取本地内存的页数,2的幂次方。
public native int pageSize();
//定义一个类,跳过JVM所有安全检查
public native Class<?> defineClass(String name, byte[] b, int off, int len,
ClassLoader loader,
ProtectionDomain protectionDomain);
//定义一个匿名类。这个匿名类不是Java层面上的匿名类,
//Java层面上的匿名内部类在VM中还是正常的,有名字的类(名字是由Java源码编译器(例如javac)构造出来的)。
public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
//创建一个对象但不会执行任何构造器,如果没有初始化进行初始化。
public native Object allocateInstance(Class<?> cls)
throws InstantiationException;
//锁定对象,必须通过monitorExit来解锁;可重入,需要monitorExit对应解锁。
public native void monitorEnter(Object o);
//解锁对象,前提是对象被monitorEnter锁了。否则抛出IllegalMonitorStateException。
public native void monitorExit(Object o);
//常识锁定对象,如果成功返回true否则false;需要monitorExit解锁。
public native boolean tryMonitorEnter(Object o);
//绕过检测机制直接抛出异常。
public native void throwException(Throwable ee);
//对于对象引用o,原子性更新offset偏移量属性值为x,当且仅当原值是expected时操作成功返回true。
public final native boolean compareAndSwapObject(Object o, long offset,
Object expected,
Object x);
//同上
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);
//从主内存中获取对象值,要求被使用的属性被volatile修饰,要不然和getObject功能一样。
public native Object getObjectVolatile(Object o, long offset);
//设置对象值,直接更新到主内存,保证对其他线程是可见的。
public native void putObjectVolatile(Object o, long offset, Object x);
public native int getIntVolatile(Object o, long offset);
public native void putIntVolatile(Object o, long offset, int x);
public native boolean getBooleanVolatile(Object o, long offset);
public native void putBooleanVolatile(Object o, long offset, boolean x);
public native byte getByteVolatile(Object o, long offset);
public native void putByteVolatile(Object o, long offset, byte x);
public native short getShortVolatile(Object o, long offset);
public native void putShortVolatile(Object o, long offset, short x);
public native char getCharVolatile(Object o, long offset);
public native void putCharVolatile(Object o, long offset, char x);
public native long getLongVolatile(Object o, long offset);
public native void putLongVolatile(Object o, long offset, long x);
public native float getFloatVolatile(Object o, long offset);
public native void putFloatVolatile(Object o, long offset, float x);
public native double getDoubleVolatile(Object o, long offset);
public native void putDoubleVolatile(Object o, long offset, double x);
//有序的或者延迟的putObjectVolatile方法,不保证值的改变对其他线程可见。
public native void putOrderedObject(Object o, long offset, Object x);
public native void putOrderedInt(Object o, long offset, int x);
public native void putOrderedLong(Object o, long offset, long x);
//释放给定park阻塞的线程,也可以解决调用park导致的阻塞。操作不安全,必须保证线程是存活的。
public native void unpark(Object thread);
//阻塞当前线程直到unpark被调用,or与其平衡的unpark已经发生,or线程被打断,
//or阻塞时间超时。
public native void park(boolean isAbsolute, long time);
//获取系统的平均负载值,loadavg这个double数组将会存放负载值的结果,nelems决定样本数量,
//nelems只能取值为1到3,分别代表最近1、5、15分钟内系统的平均负载。
//如果无法获取系统的负载,此方法返回-1,否则返回获取到的样本数量(loadavg中有效的元素个数)。
public native int getLoadAverage(double[] loadavg, int nelems);
//CAS操作
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!compareAndSwapInt(o, offset, v, v + delta));
return v;
}
public final long getAndAddLong(Object o, long offset, long delta) {
long v;
do {
v = getLongVolatile(o, offset);
} while (!compareAndSwapLong(o, offset, v, v + delta));
return v;
}
public final int getAndSetInt(Object o, long offset, int newValue) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!compareAndSwapInt(o, offset, v, newValue));
return v;
}
public final long getAndSetLong(Object o, long offset, long newValue) {
long v;
do {
v = getLongVolatile(o, offset);
} while (!compareAndSwapLong(o, offset, v, newValue));
return v;
}
public final Object getAndSetObject(Object o, long offset, Object newValue) {
Object v;
do {
v = getObjectVolatile(o, offset);
} while (!compareAndSwapObject(o, offset, v, newValue));
return v;
}
//方法前的所有读操作一定在屏障前完成,since 1.8
public native void loadFence();
//方法前的所有写操作一定在屏障前完成,since 1.8
public native void storeFence();
//方法前的所有读写操作都在屏障前完成,since 1.8
public native void fullFence();
/**
* Throws IllegalAccessError; for use by the VM.
* @since 1.8
*/
private static void throwIllegalAccessError() {
throw new IllegalAccessError();
}
}
总结
- Unsafe类可以下载openjdk看源码,在目录openjdk\jdk\src\share\classes\sun\misc中。
- Java无法直接访问到操作系统底层,而是通过native方法。
- Unsafe类提供了硬件级别的原子操作,很多Java的基础类库,包括被广泛使用的高性能开发库都有基于Unsafe类开发,如Netty、Kafka、Akka等。
- Unsafe类设计之初只是为了供标准类库使用的,因此不建议在生产环境中使用,【为什么不建议使用?看这里】
源码:openjdk-8u40-src-b25-10_feb_2015