com.github.azbh111.utils.java.unsafe.UnsafeUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
The newest version!
package com.github.azbh111.utils.java.unsafe;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* 封装Unsafe类,提供一些unsafe但又相对safe的操作
*
* @author pyz
* @date 2019/3/2 12:32 PM
*/
public class UnsafeUtils {
private static final Unsafe u;
public static final long ARRAY_BOOLEAN_BASE_OFFSET;
public static final long ARRAY_BYTE_BASE_OFFSET;
public static final long ARRAY_SHORT_BASE_OFFSET;
public static final long ARRAY_CHAR_BASE_OFFSET;
public static final long ARRAY_INT_BASE_OFFSET;
public static final long ARRAY_LONG_BASE_OFFSET;
public static final long ARRAY_FLOAT_BASE_OFFSET;
public static final long ARRAY_DOUBLE_BASE_OFFSET;
public static final long ARRAY_OBJECT_BASE_OFFSET;
/**
* 1
*/
public static final long ARRAY_BOOLEAN_INDEX_SCALE;
public static final long ARRAY_BYTE_INDEX_SCALE;
public static final long ARRAY_SHORT_INDEX_SCALE;
public static final long ARRAY_CHAR_INDEX_SCALE;
public static final long ARRAY_INT_INDEX_SCALE;
public static final long ARRAY_LONG_INDEX_SCALE;
public static final long ARRAY_FLOAT_INDEX_SCALE;
public static final long ARRAY_DOUBLE_INDEX_SCALE;
public static final long ARRAY_OBJECT_INDEX_SCALE;
public static final int ADDRESS_SIZE;
static {
try {
Class clazz = Class.forName("sun.misc.Unsafe");
Field f = clazz.getDeclaredField("theUnsafe");
f.setAccessible(true);
u = (Unsafe) f.get(null);
ARRAY_BOOLEAN_BASE_OFFSET = getInstance().arrayBaseOffset(boolean[].class);
ARRAY_BYTE_BASE_OFFSET = getInstance().arrayBaseOffset(byte[].class);
ARRAY_SHORT_BASE_OFFSET = getInstance().arrayBaseOffset(short[].class);
ARRAY_CHAR_BASE_OFFSET = getInstance().arrayBaseOffset(char[].class);
ARRAY_INT_BASE_OFFSET = getInstance().arrayBaseOffset(int[].class);
ARRAY_LONG_BASE_OFFSET = getInstance().arrayBaseOffset(long[].class);
ARRAY_FLOAT_BASE_OFFSET = getInstance().arrayBaseOffset(float[].class);
ARRAY_DOUBLE_BASE_OFFSET = getInstance().arrayBaseOffset(double[].class);
ARRAY_OBJECT_BASE_OFFSET = getInstance().arrayBaseOffset(Object[].class);
ARRAY_BOOLEAN_INDEX_SCALE = getInstance().arrayIndexScale(boolean[].class);
ARRAY_BYTE_INDEX_SCALE = getInstance().arrayIndexScale(byte[].class);
ARRAY_SHORT_INDEX_SCALE = getInstance().arrayIndexScale(short[].class);
ARRAY_CHAR_INDEX_SCALE = getInstance().arrayIndexScale(char[].class);
ARRAY_INT_INDEX_SCALE = getInstance().arrayIndexScale(int[].class);
ARRAY_LONG_INDEX_SCALE = getInstance().arrayIndexScale(long[].class);
ARRAY_FLOAT_INDEX_SCALE = getInstance().arrayIndexScale(float[].class);
ARRAY_DOUBLE_INDEX_SCALE = getInstance().arrayIndexScale(double[].class);
ARRAY_OBJECT_INDEX_SCALE = getInstance().arrayIndexScale(Object[].class);
ADDRESS_SIZE = addressSize();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static final int addressSize = getInstance().addressSize();
public static Unsafe getInstance() {
return u;
}
public static int getInt(Object o, long offset) {
return getInstance().getInt(o, offset);
}
public static void putInt(Object o, long offset, int val) {
getInstance().putInt(o, offset, val);
}
public static Object getObject(Object o, long offset) {
return getInstance().getObject(o, offset);
}
public static void putObject(Object o, long offset, Object val) {
getInstance().putObject(o, offset, val);
}
public static boolean getBoolean(Object o, long offset) {
return getInstance().getBoolean(o, offset);
}
public static void putBoolean(Object o, long offset, boolean val) {
getInstance().putBoolean(o, offset, val);
}
public static byte getByte(Object o, long offset) {
return getInstance().getByte(o, offset);
}
public static void putByte(Object o, long offset, byte val) {
getInstance().putByte(o, offset, val);
}
public static short getShort(Object o, long offset) {
return getInstance().getShort(o, offset);
}
public static void putShort(Object o, long offset, short val) {
getInstance().putShort(o, offset, val);
}
public static char getChar(Object o, long offset) {
return getInstance().getChar(o, offset);
}
public static void putChar(Object o, long offset, char val) {
getInstance().putChar(o, offset, val);
}
public static long getLong(Object o, long offset) {
return getInstance().getLong(o, offset);
}
public static void putLong(Object o, long offset, long val) {
getInstance().putLong(o, offset, val);
}
public static float getFloat(Object o, long offset) {
return getInstance().getFloat(o, offset);
}
public static void putFloat(Object o, long offset, float val) {
getInstance().putFloat(o, offset, val);
}
public static double getDouble(Object o, long offset) {
return getInstance().getDouble(o, offset);
}
public static void putDouble(Object o, long offset, double val) {
getInstance().putDouble(o, offset, val);
}
public static long staticFieldOffset(Field field) {
return getInstance().staticFieldOffset(field);
}
public static long objectFieldOffset(Field field) {
return getInstance().objectFieldOffset(field);
}
public static Object staticFieldBase(Field field) {
return getInstance().staticFieldBase(field);
}
public static int arrayBaseOffset(Class arrayClass) {
return getInstance().arrayBaseOffset(arrayClass);
}
public static int arrayIndexScale(Class> arrayClass) {
return getInstance().arrayIndexScale(arrayClass);
}
public static int addressSize() {
return getInstance().addressSize();
}
public static int pageSize() {
return getInstance().pageSize();
}
public static Object getObjectVolatile(Object o, long offset) {
return getInstance().getObjectVolatile(o, offset);
}
public static void putObjectVolatile(Object o, long offset, Object value) {
getInstance().putObjectVolatile(o, offset, value);
}
public static int getIntVolatile(Object o, long offset) {
return getInstance().getIntVolatile(o, offset);
}
public static void putIntVolatile(Object o, long offset, int value) {
getInstance().putIntVolatile(o, offset, value);
}
public static boolean getBooleanVolatile(Object o, long offset) {
return getInstance().getBooleanVolatile(o, offset);
}
public static void putBooleanVolatile(Object o, long offset, boolean value) {
getInstance().putBooleanVolatile(o, offset, value);
}
public static byte getByteVolatile(Object o, long offset) {
return getInstance().getByteVolatile(o, offset);
}
public static void putByteVolatile(Object o, long offset, byte value) {
getInstance().putByteVolatile(o, offset, value);
}
public static short getShortVolatile(Object o, long offset) {
return getInstance().getShortVolatile(o, offset);
}
public static void putShortVolatile(Object o, long offset, short value) {
getInstance().putShortVolatile(o, offset, value);
}
public static char getCharVolatile(Object o, long offset) {
return getInstance().getCharVolatile(o, offset);
}
public static void putCharVolatile(Object o, long offset, char value) {
getInstance().putCharVolatile(o, offset, value);
}
public static long getLongVolatile(Object o, long offset) {
return getInstance().getLongVolatile(o, offset);
}
public static void putLongVolatile(Object o, long offset, long value) {
getInstance().putLongVolatile(o, offset, value);
}
public static float getFloatVolatile(Object o, long offset) {
return getInstance().getFloatVolatile(o, offset);
}
public static void putFloatVolatile(Object o, long offset, float value) {
getInstance().putFloatVolatile(o, offset, value);
}
public static double getDoubleVolatile(Object o, long offset) {
return getInstance().getDoubleVolatile(o, offset);
}
public static void putDoubleVolatile(Object o, long offset, double value) {
getInstance().putDoubleVolatile(o, offset, value);
}
public static void putOrderedObject(Object o, long offset, Object value) {
getInstance().putOrderedObject(o, offset, value);
}
public static void putOrderedInt(Object o, long offset, int value) {
getInstance().putOrderedInt(o, offset, value);
}
public static void putOrderedLong(Object o, long offset, long value) {
getInstance().putOrderedLong(o, offset, value);
}
public static boolean compareAndSwapObject(Object o, long offset, Object oldVal, Object newVal) {
return getInstance().compareAndSwapObject(o, offset, oldVal, newVal);
}
public static boolean compareAndSwapInt(Object o, long offset, int oldVal, int newVal) {
return getInstance().compareAndSwapInt(o, offset, oldVal, newVal);
}
public static boolean compareAndSwapLong(Object o, long offset, long oldVal, long newVal) {
return getInstance().compareAndSwapLong(o, offset, oldVal, newVal);
}
public static int getAndAddInt(Object o, long offset, int newValue) {
return getInstance().getAndAddInt(o, offset, newValue);
}
public static long getAndAddLong(Object o, long offset, long newValue) {
return getInstance().getAndAddLong(o, offset, newValue);
}
public static int getAndSetInt(Object o, long offset, int newValue) {
return getInstance().getAndSetInt(o, offset, newValue);
}
public static long getAndSetLong(Object o, long offset, long newValue) {
return getInstance().getAndSetLong(o, offset, newValue);
}
public static Object getAndSetObject(Object o, long offset, Object newValue) {
return getInstance().getAndSetObject(o, offset, newValue);
}
public static void loadFence() {
getInstance().loadFence();
}
public static void storeFence() {
getInstance().storeFence();
}
public static void fullFence() {
getInstance().fullFence();
}
/**
* 获取对象的内存地址
*
* @param obj
* @return
*/
public static long getAddress(Object obj) {
Object[] array = new Object[]{obj};
switch (ADDRESS_SIZE) {
case 4:
return getInstance().getInt(array, ARRAY_OBJECT_BASE_OFFSET);
case 8:
return getInstance().getLong(array, ARRAY_OBJECT_BASE_OFFSET);
default:
throw new Error("unsupported address size: " + ADDRESS_SIZE);
}
}
/**
* 直接创建对象,不会触发初始化代码块和构造函数
*
* @param t
* @param
* @return
* @throws InstantiationException
*/
public static T allocateInstance(Class t) throws InstantiationException {
return (T) getInstance().allocateInstance(t);
}
/**
* 经常需要catch受检查的异常,然后用某个不受检查的异常包装并抛出
*
* 用这个方法可以直接抛不受检查的异常
* 例: UnsafeUtils.throwException(new Exception());throw new RuntimeException();
* 这里throw new RuntimeException();只起中断作用,永远不会被执行
*
* @param e
*/
public static void throwException(Throwable e) {
getInstance().throwException(e);
}
}