摘要:源碼閱讀創(chuàng)建鎖和同步類中使用的基礎(chǔ)的線程阻塞原語除非你是多線程專家,而且你要自己設(shè)計(jì)和實(shí)現(xiàn)阻塞式線程同步機(jī)制比如等等,否則你不需要用和。
LockSupport源碼閱讀
/* * 創(chuàng)建鎖和同步類中使用的基礎(chǔ)的線程阻塞原語 * * 除非你是多線程專家,而且你要自己設(shè)計(jì)和實(shí)現(xiàn)阻塞式線程同步機(jī)制(比如lock、condition等等),否則你不需要用park和unpark。這兩個(gè)原語是用來實(shí)現(xiàn)這些的,不是給應(yīng)用程序用的 */ public class LockSupport { //私有構(gòu)造方法,不能被實(shí)例化 private LockSupport() {} //把 Thread 實(shí)例 t 的 parkBlocker 字段的值設(shè)置為 arg private static void setBlocker(Thread t, Object arg) { UNSAFE.putObject(t, parkBlockerOffset, arg); } /** * 如果給定線程的許可不可用,使其可用。 * 如果線程在 park上受阻塞,則它將解除其阻塞狀態(tài)。否則,保證下一次調(diào) * 用 park 不會(huì)受阻塞。 * 如果給定線程尚未啟動(dòng),則無法保證此操作有任何效果。 */ public static void unpark(Thread thread) { if (thread != null) UNSAFE.unpark(thread); } public static void park(Object blocker) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(false, 0L); setBlocker(t, null); } /** * 帶超時(shí)時(shí)間的park */ public static void parkNanos(Object blocker, long nanos) { if (nanos > 0) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(false, nanos); setBlocker(t, null); } } /** * 在deadline時(shí)間內(nèi),park */ public static void parkUntil(Object blocker, long deadline) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(true, deadline); setBlocker(t, null); } /** * 返回提供給最近一次尚未解除阻塞的 park 方法調(diào)用的 blocker 對(duì)象,如果該調(diào)用不受阻塞,則返回 null。 * 返回的值只是一個(gè)瞬間快照,即由于未解除阻塞或者在不同的 blocker 對(duì)象上受阻而具有的線程。 */ public static Object getBlocker(Thread t) { if (t == null) throw new NullPointerException(); return UNSAFE.getObjectVolatile(t, parkBlockerOffset); } /** * 為了線程調(diào)度,禁用當(dāng)前線程,除非有許可 * 如果許可可用,使用改許可,且調(diào)用立即返回。否則,為進(jìn)程調(diào)度禁用當(dāng)前 * 線程,直到發(fā)生以下三件事之前一直休眠 * * 1、其它線程觸發(fā)當(dāng)前線程的unpark * 2、其它線程中斷當(dāng)前線程 * 3、毫無邏輯的返回 * 此方法不返回誰引起此方法返回,調(diào)用方應(yīng)該重新檢查誰最先park此線程, * 調(diào)用方也可以決定此線程返回時(shí)的中斷狀態(tài) */ public static void park() { UNSAFE.park(false, 0L); } /** * 帶超時(shí)時(shí)間的park */ public static void parkNanos(long nanos) { if (nanos > 0) UNSAFE.park(false, nanos); } /** * 在deadline時(shí)間內(nèi),park */ public static void parkUntil(long deadline) { UNSAFE.park(true, deadline); } /** * Returns the pseudo-randomly initialized or updated secondary seed. * Copied from ThreadLocalRandom due to package access restrictions. */ static final int nextSecondarySeed() { int r; Thread t = Thread.currentThread(); if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { r ^= r << 13; // xorshift r ^= r >>> 17; r ^= r << 5; } else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0) r = 1; // avoid zero UNSAFE.putInt(t, SECONDARY, r); return r; } //引用Unsafe類 private static final sun.misc.Unsafe UNSAFE; //Thread類中 parkBlocker 字段的偏移量 private static final long parkBlockerOffset; //Thread 類中 threadLocalRandomSeed 字段的偏移量 private static final long SEED; //Thread 類中 threadLocalRandomProbe 字段的偏移量 private static final long PROBE; //Thread 類中 threadLocalRandomSecondarySeed 字段的偏移量 private static final long SECONDARY; //初始化上面4個(gè)字段的值 static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class> tk = Thread.class; parkBlockerOffset = UNSAFE.objectFieldOffset (tk.getDeclaredField("parkBlocker")); SEED = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomSeed")); PROBE = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomProbe")); SECONDARY = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomSecondarySeed")); } catch (Exception ex) { throw new Error(ex); } }
參考:Java的LockSupport.park()實(shí)現(xiàn)分析
使用方法:LockSupport的使用
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70071.html
摘要:中斷狀態(tài)可以通過來讀取,并且可以通過一個(gè)名為的操作讀取和清除。中斷的協(xié)作特性所帶來的一個(gè)好處是,它為安全地構(gòu)造可取消活動(dòng)提供更大的靈活性。中斷允許一個(gè)可取消活動(dòng)來清理正在進(jìn)行的工作,恢復(fù)不變量,通知其他活動(dòng)它要被取消,然后才終止。 Thread實(shí)現(xiàn)Runnable接口 1.Thread內(nèi)部有個(gè)State枚舉,標(biāo)示著線程的狀態(tài)。 NEW,新建未開始 RUNNABLE,可執(zhí)行 BLOCK...
摘要:前言本來準(zhǔn)備做源碼閱讀的幾千行看著太累了看了幾篇大神的文章后才基本搞懂附在這里閱讀本文前請(qǐng)先看懂的介紹和原理分析并發(fā)包源碼學(xué)習(xí)之框架四源碼分析接口實(shí)現(xiàn)接口一般看一個(gè)類實(shí)現(xiàn)的接口可以看出它的目的其實(shí)也是熟悉的目的主要是替代的方法的它是基于實(shí)現(xiàn) 前言 本來準(zhǔn)備做AbstractQueuedSynchronizer源碼閱讀的,幾千行看著太累了,看了幾篇大神的文章后才基本搞懂,附在這里,閱讀本...
摘要:此對(duì)象在線程受阻塞時(shí)被記錄,以允許監(jiān)視工具和診斷工具確定線程受阻塞的原因。調(diào)用該線程變量的方法,會(huì)喚醒該線程,并拋出異常。對(duì)于等待狀態(tài)來說,它比狀態(tài)多了一種喚醒方式,就是超過規(guī)定時(shí)間,那么線程會(huì)自動(dòng)醒來。 一. LockSupport類介紹 LockSupport類可以阻塞當(dāng)前線程以及喚醒指定被阻塞的線程。主要是通過park()和unpark(thread)方法來實(shí)現(xiàn)阻塞和喚醒線程的操...
摘要:此對(duì)象在線程受阻塞時(shí)被記錄,以允許監(jiān)視工具和診斷工具確定線程受阻塞的原因。阻塞當(dāng)前線程,最長(zhǎng)不超過納秒,返回條件在的基礎(chǔ)上增加了超時(shí)返回。喚醒線程喚醒處于阻塞狀態(tài)的線程。 LockSupport 用法簡(jiǎn)介 LockSupport 和 CAS 是Java并發(fā)包中很多并發(fā)工具控制機(jī)制的基礎(chǔ),它們底層其實(shí)都是依賴Unsafe實(shí)現(xiàn)。 LockSupport是用來創(chuàng)建鎖和其他同步類的基本線程阻塞...
摘要:今天在群上拋出來一個(gè)問題,如下我以自帶的數(shù)據(jù)結(jié)構(gòu)為例,用源碼的形式說明,如何阻塞線程通知線程的。一以可重入鎖和兩個(gè)對(duì)象來控制并發(fā)。四使用來控制并發(fā),同時(shí)也使用的對(duì)象來與線程交互。 今天在QQ群上拋出來一個(gè)問題,如下showImg(https://segmentfault.com/img/bV1dEB?w=422&h=132); 我以Java自帶的數(shù)據(jù)結(jié)構(gòu)為例,用源碼的形式說明,如何阻塞...
閱讀 1498·2021-11-24 11:16
閱讀 2706·2021-07-28 12:32
閱讀 2312·2019-08-30 11:22
閱讀 1452·2019-08-30 11:01
閱讀 608·2019-08-29 16:24
閱讀 3554·2019-08-29 12:52
閱讀 1635·2019-08-29 12:15
閱讀 1344·2019-08-29 11:18