All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.unsafe.UnsafeUtils Maven / Gradle / Ivy

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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy