LockSupport源码解析
LockSupport 这个类基本就是对Unsafe中park,unpark方法的包装,LockSupport不可以实例化。
1 public class LockSupport { 2 3 //Cannot be instantiated. 4 private LockSupport() {} 5 6 //替换Thread中parkBlocker属性的值为arg 7 private static void setBlocker(Thread t, Object arg) { 8 UNSAFE.putObject(t, parkBlockerOffset, arg); 9 } 10 11 12 //唤醒thread线程 13 public static void unpark(Thread thread) { 14 if (thread != null) 15 UNSAFE.unpark(thread); 16 } 17 18 //堵塞线程,堵塞前把当前线程属性名是parkBlocker的变量替换成blocker 19 //返回后值为null 20 public static void park(Object blocker) { 21 Thread t = Thread.currentThread(); 22 setBlocker(t, blocker); 23 UNSAFE.park(false, 0L); 24 setBlocker(t, null); 25 } 26 27 //和park(Object blocker)类似,增加了堵塞的纳秒数,都是相对时间 28 public static void parkNanos(Object blocker, long nanos) { 29 if (nanos > 0) { 30 Thread t = Thread.currentThread(); 31 setBlocker(t, blocker); 32 UNSAFE.park(false, nanos); 33 setBlocker(t, null); 34 } 35 } 36 37 //绝对时间堵塞 38 public static void parkUntil(Object blocker, long deadline) { 39 Thread t = Thread.currentThread(); 40 setBlocker(t, blocker); 41 UNSAFE.park(true, deadline); 42 setBlocker(t, null); 43 } 44 45 //获取堵塞的时候设置的对象,parkBlockerOffset 是Thread 中属性值是parkBlocker的偏移量(地址) 46 public static Object getBlocker(Thread t) { 47 if (t == null) 48 throw new NullPointerException(); 49 return UNSAFE.getObjectVolatile(t, parkBlockerOffset); 50 } 51 52 //直接堵塞, 53 public static void park() { 54 UNSAFE.park(false, 0L); 55 } 56 57 //堵塞,相对时间 58 public static void parkNanos(long nanos) { 59 if (nanos > 0) 60 UNSAFE.park(false, nanos); 61 } 62 63 //堵塞 绝对时间 64 public static void parkUntil(long deadline) { 65 UNSAFE.park(true, deadline); 66 } 67 68 //根据当前线程中属性名是threadLocalRandomSecondarySeed的变量生成随机数 69 static final int nextSecondarySeed() { 70 int r; 71 Thread t = Thread.currentThread(); 72 if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { 73 r ^= r << 13; // xorshift 74 r ^= r >>> 17; 75 r ^= r << 5; 76 } 77 else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0) 78 r = 1; // avoid zero 79 UNSAFE.putInt(t, SECONDARY, r); 80 return r; 81 } 82 83 //以下属性是根据Unsafe中的objectFieldOffset方法获取Thread属性的偏移量(地址) 84 private static final sun.misc.Unsafe UNSAFE; 85 private static final long parkBlockerOffset; 86 private static final long SEED; 87 private static final long PROBE; 88 private static final long SECONDARY; 89 static { 90 try { 91 UNSAFE = sun.misc.Unsafe.getUnsafe(); 92 Class<?> tk = Thread.class; 93 94 parkBlockerOffset = UNSAFE.objectFieldOffset(tk.getDeclaredField("parkBlocker")); 95 96 SEED = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSeed")); 97 98 PROBE = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomProbe")); 99 100 SECONDARY = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomSecondarySeed")); 101 102 } catch (Exception ex) { throw new Error(ex); } 103 } 104 105 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步