Java執行緒--LockSupport阻塞/喚醒工具類
阿新 • • 發佈:2018-12-20
LockSupport執行緒阻塞/喚醒工具類
目錄
LockSupport原理
LockSupport類,是個工具類。內部的實現是呼叫sun.misc.Unsafe(rt.jar包中)這個native本地類中的方法實現的,Unsafe本地類是用C++寫的。可以說concurrent包中的絕大部分類都是最終呼叫到了Unsafe類中的方法,下面附上Unsafe類的部分原始碼及其說明:
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; /** * volatile, CAS操作, 自旋結構 組合在一起構成了java.util.concurrent包 * * volatile 修飾的變數如果是物件或陣列,其含義是物件或陣列的地址具有可見性,但是陣列或物件內部的成員改變不具備可見性 * * CAS操作; lock字首指令,執行該cas指令時會鎖住緩衝行 * *自旋結構; for(;;){ 讀記憶體值; if(cas操作){return;} } */ //Unsafe類在%JAVA_HOME%/jre/lib/rt.jar包中 public final class Unsafe { private static final Unsafe theUnsafe = new Unsafe(); public static final int INVALID_FIELD_OFFSET = -1; /******************LockSupport類呼叫的****************************/ public native void unpark(Object paramObject); public native void park(boolean paramBoolean, long paramLong); /******************AtomicReference<T>類呼叫的****************************/ /** * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapObject){return;} } * 引數 paramObject1 cpu舊值 * 引數 paramLong 偏移量 * 引數 paramObject2 cpu新值 */ public final Object getAndSetObject(Object paramObject1, long paramLong, Object paramObject2) { Object localObject; do { localObject = getObjectVolatile(paramObject1, paramLong); } while (!compareAndSwapObject(paramObject1, paramLong, localObject, paramObject2)); return localObject; } //原子操作:比較並轉換:cpu內舊值paramObject1, 偏移量paramLong, 記憶體當前值paramObject2, cpu內新值paramObject3 public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3); //原子操作:讀取可見性記憶體值 public native Object getObjectVolatile(Object paramObject, long paramLong); /******************AtomicInteger類呼叫的****************************/ /** * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapInt){return;} } * 引數 paramObject1 cpu舊值 * 引數 paramLong 偏移量 * 引數 paramInt 累加 */ public final int getAndAddInt(Object paramObject, long paramLong, int paramInt) { int i; do { i = getIntVolatile(paramObject, paramLong); } while (!compareAndSwapInt(paramObject, paramLong, i, i + paramInt)); return i; } //原子操作:比較並轉換:cpu內舊值paramObject1, 偏移量paramLong, 記憶體當前值paramObject2, cpu內新值paramObject3 public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2); public native int getIntVolatile(Object paramObject, long paramLong); /** * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapInt){return;} } * 引數 paramObject cpu舊值 * 引數 paramLong 偏移量 * 引數 paramInt cpu新值 */ public final int getAndSetInt(Object paramObject, long paramLong, int paramInt) { int i; do { i = getIntVolatile(paramObject, paramLong); } while (!compareAndSwapInt(paramObject, paramLong, i, paramInt)); return i; } public void setMemory(long paramLong1, long paramLong2, byte paramByte) { setMemory(null, paramLong1, paramLong2, paramByte); } public void copyMemory(long paramLong1, long paramLong2, long paramLong3) { copyMemory(null, paramLong1, null, paramLong2, paramLong3); } public native void setMemory(Object paramObject, long paramLong1, long paramLong2, byte paramByte); public native void copyMemory(Object paramObject1, long paramLong1, Object paramObject2, long paramLong2, long paramLong3); }
- park()方法的本質可以理解為:雷同Object物件的wait()方法,作用是將當前執行緒阻塞
- unpark()方法的本質可以理解為:雷同Object物件的notify()方法,作用是將執行緒喚醒
LockSupport示例