摘要:初始時,為,當調(diào)用方法時,線程的加,當調(diào)用方法時,如果為,則調(diào)用線程進入阻塞狀態(tài)。該對象一般供監(jiān)視診斷工具確定線程受阻塞的原因時使用。
本文首發(fā)于一世流云的專欄:https://segmentfault.com/blog...一、LockSupport類簡介
LockSupport類,是JUC包中的一個工具類,是用來創(chuàng)建鎖和其他同步類的基本線程阻塞原語。(Basic thread blocking primitives for creating locks and other synchronization classes)
LockSupport類的核心方法其實就兩個:park()和unark(),其中park()方法用來阻塞當前調(diào)用線程,unpark()方法用于喚醒指定線程。
這其實和Object類的wait()和signial()方法有些類似,但是LockSupport的這兩種方法從語意上講比Object類的方法更清晰,而且可以針對指定線程進行阻塞和喚醒。
LockSupport類使用了一種名為Permit(許可)的概念來做到阻塞和喚醒線程的功能,可以把許可看成是一種(0,1)信號量(Semaphore),但與 Semaphore 不同的是,許可的累加上限是1。1.1 使用示例
初始時,permit為0,當調(diào)用unpark()方法時,線程的permit加1,當調(diào)用park()方法時,如果permit為0,則調(diào)用線程進入阻塞狀態(tài)。
來看一個例子:
假設現(xiàn)在需要實現(xiàn)一種FIFO類型的獨占鎖,可以把這種鎖看成是ReentrantLock的公平鎖簡單版本,且是不可重入的,就是說當一個線程獲得鎖后,其它等待線程以FIFO的調(diào)度方式等待獲取鎖。
public class FIFOMutex { private final AtomicBoolean locked = new AtomicBoolean(false); private final Queuewaiters = new ConcurrentLinkedQueue (); ? public void lock() { Thread current = Thread.currentThread(); waiters.add(current); ? // 如果當前線程不在隊首,或鎖已被占用,則當前線程阻塞 // NOTE:這個判斷的意圖其實就是:鎖必須由隊首元素拿到 while (waiters.peek() != current || !locked.compareAndSet(false, true)) { LockSupport.park(this); } waiters.remove(); // 刪除隊首元素 } ? public void unlock() { locked.set(false); LockSupport.unpark(waiters.peek()); } }
測試用例:
public class Main { public static void main(String[] args) throws InterruptedException { FIFOMutex mutex = new FIFOMutex(); MyThread a1 = new MyThread("a1", mutex); MyThread a2 = new MyThread("a2", mutex); MyThread a3 = new MyThread("a3", mutex); ? a1.start(); a2.start(); a3.start(); ? a1.join(); a2.join(); a3.join(); ? assert MyThread.count == 300; System.out.print("Finished"); } } ? class MyThread extends Thread { private String name; private FIFOMutex mutex; public static int count; ? public MyThread(String name, FIFOMutex mutex) { this.name = name; this.mutex = mutex; } ? @Override public void run() { for (int i = 0; i < 100; i++) { mutex.lock(); count++; System.out.println("name:" + name + " count:" + count); mutex.unlock(); } } }
上述FIFOMutex 類的實現(xiàn)中,當判斷鎖已被占用時,會調(diào)用LockSupport.park(this)方法,將當前調(diào)用線程阻塞;當使用完鎖時,會調(diào)用LockSupport.unpark(waiters.peek())方法將等待隊列中的隊首線程喚醒。
通過LockSupport的這兩個方法,可以很方便的阻塞和喚醒線程。但是LockSupport的使用過程中還需要注意以下幾點:
park方法的調(diào)用一般要方法一個循環(huán)判斷體里面。
如上述示例中的:
while (waiters.peek() != current || !locked.compareAndSet(false, true)) { LockSupport.park(this); }
之所以這樣做,是為了防止線程被喚醒后,不進行判斷而意外繼續(xù)向下執(zhí)行,這其實是一種Guarded Suspension的多線程設計模式。
park方法是會響應中斷的,但是不會拋出異常。(也就是說如果當前調(diào)用線程被中斷,則會立即返回但不會拋出中斷異常)
park的重載方法park(Object blocker),會傳入一個blocker對象,所謂Blocker對象,其實就是當前線程調(diào)用時所在調(diào)用對象(如上述示例中的FIFOMutex對象)。該對象一般供監(jiān)視、診斷工具確定線程受阻塞的原因時使用。
二、LockSupport類/方法聲明類聲明:
方法聲明:
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/71523.html
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見的多線程設計模式,設計了并發(fā)包,其中包下提供了一系列基礎的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專欄:https...
摘要:開始獲取鎖終于輪到出場了,的調(diào)用過程和完全一樣,同樣拿不到鎖,然后加入到等待隊列隊尾然后,在阻塞前需要把前驅(qū)結(jié)點的狀態(tài)置為,以確保將來可以被喚醒至此,的執(zhí)行也暫告一段落了安心得在等待隊列中睡覺。 showImg(https://segmentfault.com/img/remote/1460000016012467); 本文首發(fā)于一世流云的專欄:https://segmentfault...
摘要:的引入先來看下,為什么有了,還要引入使得多個讀線程同時持有讀鎖只要寫鎖未被占用,而寫鎖是獨占的。部分常量的比特位表示如下另外,相比,對多核進行了優(yōu)化,可以看到,當核數(shù)超過時,會有一些自旋操作示例分析假設現(xiàn)在有三個線程。 showImg(https://segmentfault.com/img/remote/1460000016012263); 本文首發(fā)于一世流云的專欄:https://...
摘要:在時,引入了包,該包中的大多數(shù)同步器都是基于來構(gòu)建的??蚣芴峁┝艘惶淄ㄓ玫臋C制來管理同步狀態(tài)阻塞喚醒線程管理等待隊列。指針用于在結(jié)點線程被取消時,讓當前結(jié)點的前驅(qū)直接指向當前結(jié)點的后驅(qū)完成出隊動作。 showImg(https://segmentfault.com/img/remote/1460000016012438); 本文首發(fā)于一世流云的專欄:https://segmentfau...
摘要:公平策略在多個線程爭用鎖的情況下,公平策略傾向于將訪問權授予等待時間最長的線程。使用方式的典型調(diào)用方式如下二類原理的源碼非常簡單,它通過內(nèi)部類實現(xiàn)了框架,接口的實現(xiàn)僅僅是對的的簡單封裝,參見原理多線程進階七鎖框架獨占功能剖析 showImg(https://segmentfault.com/img/remote/1460000016012582); 本文首發(fā)于一世流云的專欄:https...
閱讀 2788·2023-04-26 01:47
閱讀 3597·2023-04-25 23:45
閱讀 2474·2021-10-13 09:39
閱讀 612·2021-10-09 09:44
閱讀 1799·2021-09-22 15:59
閱讀 2773·2021-09-13 10:33
閱讀 1723·2021-09-03 10:30
閱讀 662·2019-08-30 15:53