今天查看hadoop源代码, 发现有个Unsafe.java
稍微总结下
优势 1 减少线程调度开销, Unsafe.java 通过采用非堵塞原子方式来减少线程调度开销
2 传统线程通信通过wait,notify方法实现(会有信号量的堵塞队列),而Unsafe使用操作系统调度命令park,unpark, 减少信号量的开销,提高新能。
差不多和windows下的InterlockedDecrement差不多的概念, 只是Unsafe的功能更加强大,可以获取的类型更多,另外可以有C/C++方式的内存分配模式以及内存交换等更多操作
Java中不直接使用Unsafe.java,封装成原子类给用户使用
public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset;
其他还有很多类型.
附源代码
/*** Eclipse Class Decompiler plugin, copyright (c) 2012 Chao Chen (cnfree2000@hotmail.com) ***/ package sun.misc; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.ProtectionDomain; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; public final class Unsafe { private static final Unsafe theUnsafe; public static final int INVALID_FIELD_OFFSET = -1; public static final int ARRAY_BOOLEAN_BASE_OFFSET; public static final int ARRAY_BYTE_BASE_OFFSET; public static final int ARRAY_SHORT_BASE_OFFSET; public static final int ARRAY_CHAR_BASE_OFFSET; public static final int ARRAY_INT_BASE_OFFSET; public static final int ARRAY_LONG_BASE_OFFSET; public static final int ARRAY_FLOAT_BASE_OFFSET; public static final int ARRAY_DOUBLE_BASE_OFFSET; public static final int ARRAY_OBJECT_BASE_OFFSET; public static final int ARRAY_BOOLEAN_INDEX_SCALE; public static final int ARRAY_BYTE_INDEX_SCALE; public static final int ARRAY_SHORT_INDEX_SCALE; public static final int ARRAY_CHAR_INDEX_SCALE; public static final int ARRAY_INT_INDEX_SCALE; public static final int ARRAY_LONG_INDEX_SCALE; public static final int ARRAY_FLOAT_INDEX_SCALE; public static final int ARRAY_DOUBLE_INDEX_SCALE; public static final int ARRAY_OBJECT_INDEX_SCALE; public static final int ADDRESS_SIZE; private static native void registerNatives(); @CallerSensitive public static Unsafe getUnsafe() { Class localClass = Reflection.getCallerClass(); if (localClass.getClassLoader() != null) throw new SecurityException("Unsafe"); return theUnsafe; } public native int getInt(Object paramObject, long paramLong); public native void putInt(Object paramObject, long paramLong, int paramInt); public native Object getObject(Object paramObject, long paramLong); public native void putObject(Object paramObject1, long paramLong, Object paramObject2); public native boolean getBoolean(Object paramObject, long paramLong); public native void putBoolean(Object paramObject, long paramLong, boolean paramBoolean); public native byte getByte(Object paramObject, long paramLong); public native void putByte(Object paramObject, long paramLong, byte paramByte); public native short getShort(Object paramObject, long paramLong); public native void putShort(Object paramObject, long paramLong, short paramShort); public native char getChar(Object paramObject, long paramLong); public native void putChar(Object paramObject, long paramLong, char paramChar); public native long getLong(Object paramObject, long paramLong); public native void putLong(Object paramObject, long paramLong1, long paramLong2); public native float getFloat(Object paramObject, long paramLong); public native void putFloat(Object paramObject, long paramLong, float paramFloat); public native double getDouble(Object paramObject, long paramLong); public native void putDouble(Object paramObject, long paramLong, double paramDouble); @Deprecated public int getInt(Object paramObject, int paramInt) { return getInt(paramObject, paramInt); } @Deprecated public void putInt(Object paramObject, int paramInt1, int paramInt2) { putInt(paramObject, paramInt1, paramInt2); } @Deprecated public Object getObject(Object paramObject, int paramInt) { return getObject(paramObject, paramInt); } @Deprecated public void putObject(Object paramObject1, int paramInt, Object paramObject2) { putObject(paramObject1, paramInt, paramObject2); } @Deprecated public boolean getBoolean(Object paramObject, int paramInt) { return getBoolean(paramObject, paramInt); } @Deprecated public void putBoolean(Object paramObject, int paramInt, boolean paramBoolean) { putBoolean(paramObject, paramInt, paramBoolean); } @Deprecated public byte getByte(Object paramObject, int paramInt) { return getByte(paramObject, paramInt); } @Deprecated public void putByte(Object paramObject, int paramInt, byte paramByte) { putByte(paramObject, paramInt, paramByte); } @Deprecated public short getShort(Object paramObject, int paramInt) { return getShort(paramObject, paramInt); } @Deprecated public void putShort(Object paramObject, int paramInt, short paramShort) { putShort(paramObject, paramInt, paramShort); } @Deprecated public char getChar(Object paramObject, int paramInt) { return getChar(paramObject, paramInt); } @Deprecated public void putChar(Object paramObject, int paramInt, char paramChar) { putChar(paramObject, paramInt, paramChar); } @Deprecated public long getLong(Object paramObject, int paramInt) { return getLong(paramObject, paramInt); } @Deprecated public void putLong(Object paramObject, int paramInt, long paramLong) { putLong(paramObject, paramInt, paramLong); } @Deprecated public float getFloat(Object paramObject, int paramInt) { return getFloat(paramObject, paramInt); } @Deprecated public void putFloat(Object paramObject, int paramInt, float paramFloat) { putFloat(paramObject, paramInt, paramFloat); } @Deprecated public double getDouble(Object paramObject, int paramInt) { return getDouble(paramObject, paramInt); } @Deprecated public void putDouble(Object paramObject, int paramInt, double paramDouble) { putDouble(paramObject, paramInt, paramDouble); } public native byte getByte(long paramLong); public native void putByte(long paramLong, byte paramByte); public native short getShort(long paramLong); public native void putShort(long paramLong, short paramShort); public native char getChar(long paramLong); public native void putChar(long paramLong, char paramChar); public native int getInt(long paramLong); public native void putInt(long paramLong, int paramInt); public native long getLong(long paramLong); public native void putLong(long paramLong1, long paramLong2); public native float getFloat(long paramLong); public native void putFloat(long paramLong, float paramFloat); public native double getDouble(long paramLong); public native void putDouble(long paramLong, double paramDouble); public native long getAddress(long paramLong); public native void putAddress(long paramLong1, long paramLong2); public native long allocateMemory(long paramLong); public native long reallocateMemory(long paramLong1, long paramLong2); public native void setMemory(Object paramObject, long paramLong1, long paramLong2, byte paramByte); public void setMemory(long paramLong1, long paramLong2, byte paramByte) { setMemory(null, paramLong1, paramLong2, paramByte); } public native void copyMemory(Object paramObject1, long paramLong1, Object paramObject2, long paramLong2, long paramLong3); public void copyMemory(long paramLong1, long paramLong2, long paramLong3) { copyMemory(null, paramLong1, null, paramLong2, paramLong3); } public native void freeMemory(long paramLong); @Deprecated public int fieldOffset(Field paramField) { if (Modifier.isStatic(paramField.getModifiers())) { return (int)staticFieldOffset(paramField); } return (int)objectFieldOffset(paramField); } @Deprecated public Object staticFieldBase(Class paramClass) { Field[] arrayOfField = paramClass.getDeclaredFields(); for (int i = 0; i < arrayOfField.length; ++i) { if (Modifier.isStatic(arrayOfField[i].getModifiers())) { return staticFieldBase(arrayOfField[i]); } } return null; } public native long staticFieldOffset(Field paramField); public native long objectFieldOffset(Field paramField); public native Object staticFieldBase(Field paramField); public native boolean shouldBeInitialized(Class<?> paramClass); public native void ensureClassInitialized(Class paramClass); public native int arrayBaseOffset(Class paramClass); public native int arrayIndexScale(Class paramClass); public native int addressSize(); public native int pageSize(); public native Class defineClass(String paramString, byte[] paramArrayOfByte, int paramInt1, int paramInt2, ClassLoader paramClassLoader, ProtectionDomain paramProtectionDomain); @Deprecated @CallerSensitive public native Class defineClass(String paramString, byte[] paramArrayOfByte, int paramInt1, int paramInt2); public native Class defineAnonymousClass(Class paramClass, byte[] paramArrayOfByte, Object[] paramArrayOfObject); public native Object allocateInstance(Class paramClass) throws InstantiationException; public native void monitorEnter(Object paramObject); public native void monitorExit(Object paramObject); public native boolean tryMonitorEnter(Object paramObject); public native void throwException(Throwable paramThrowable); public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3); public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2); public final native boolean compareAndSwapLong(Object paramObject, long paramLong1, long paramLong2, long paramLong3); public native Object getObjectVolatile(Object paramObject, long paramLong); public native void putObjectVolatile(Object paramObject1, long paramLong, Object paramObject2); public native int getIntVolatile(Object paramObject, long paramLong); public native void putIntVolatile(Object paramObject, long paramLong, int paramInt); public native boolean getBooleanVolatile(Object paramObject, long paramLong); public native void putBooleanVolatile(Object paramObject, long paramLong, boolean paramBoolean); public native byte getByteVolatile(Object paramObject, long paramLong); public native void putByteVolatile(Object paramObject, long paramLong, byte paramByte); public native short getShortVolatile(Object paramObject, long paramLong); public native void putShortVolatile(Object paramObject, long paramLong, short paramShort); public native char getCharVolatile(Object paramObject, long paramLong); public native void putCharVolatile(Object paramObject, long paramLong, char paramChar); public native long getLongVolatile(Object paramObject, long paramLong); public native void putLongVolatile(Object paramObject, long paramLong1, long paramLong2); public native float getFloatVolatile(Object paramObject, long paramLong); public native void putFloatVolatile(Object paramObject, long paramLong, float paramFloat); public native double getDoubleVolatile(Object paramObject, long paramLong); public native void putDoubleVolatile(Object paramObject, long paramLong, double paramDouble); public native void putOrderedObject(Object paramObject1, long paramLong, Object paramObject2); public native void putOrderedInt(Object paramObject, long paramLong, int paramInt); public native void putOrderedLong(Object paramObject, long paramLong1, long paramLong2); public native void unpark(Object paramObject); public native void park(boolean paramBoolean, long paramLong); public native int getLoadAverage(double[] paramArrayOfDouble, int paramInt); static { registerNatives(); Reflection.registerMethodsToFilter(Unsafe.class, new String[] { "getUnsafe" }); theUnsafe = new Unsafe(); ARRAY_BOOLEAN_BASE_OFFSET = theUnsafe.arrayBaseOffset([Z.class); ARRAY_BYTE_BASE_OFFSET = theUnsafe.arrayBaseOffset([B.class); ARRAY_SHORT_BASE_OFFSET = theUnsafe.arrayBaseOffset([S.class); ARRAY_CHAR_BASE_OFFSET = theUnsafe.arrayBaseOffset([C.class); ARRAY_INT_BASE_OFFSET = theUnsafe.arrayBaseOffset([I.class); ARRAY_LONG_BASE_OFFSET = theUnsafe.arrayBaseOffset([J.class); ARRAY_FLOAT_BASE_OFFSET = theUnsafe.arrayBaseOffset([F.class); ARRAY_DOUBLE_BASE_OFFSET = theUnsafe.arrayBaseOffset([D.class); ARRAY_OBJECT_BASE_OFFSET = theUnsafe.arrayBaseOffset([Ljava.lang.Object.class); ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale([Z.class); ARRAY_BYTE_INDEX_SCALE = theUnsafe.arrayIndexScale([B.class); ARRAY_SHORT_INDEX_SCALE = theUnsafe.arrayIndexScale([S.class); ARRAY_CHAR_INDEX_SCALE = theUnsafe.arrayIndexScale([C.class); ARRAY_INT_INDEX_SCALE = theUnsafe.arrayIndexScale([I.class); ARRAY_LONG_INDEX_SCALE = theUnsafe.arrayIndexScale([J.class); ARRAY_FLOAT_INDEX_SCALE = theUnsafe.arrayIndexScale([F.class); ARRAY_DOUBLE_INDEX_SCALE = theUnsafe.arrayIndexScale([D.class); ARRAY_OBJECT_INDEX_SCALE = theUnsafe.arrayIndexScale([Ljava.lang.Object.class); ADDRESS_SIZE = theUnsafe.addressSize(); } }