亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

教你如何使用Java多線程編程LockSupport工具類

瀏覽:22日期:2022-08-14 13:43:16
LockSupport類

用于創(chuàng)建鎖和其他同步類的基本線程阻塞原語(yǔ),此類與使用它的每個(gè)線程關(guān)聯(lián)一個(gè)許可。如果獲得許可,將立即返回對(duì)park的調(diào)用,并在此過(guò)程中消耗掉它;否則may會(huì)被阻止。調(diào)用unpark可使許可證可用(如果尚不可用)。(不過(guò)與信號(hào)量不同,許可證不會(huì)累積。最多只能有一個(gè)。)方法park和unpark提供了有效的阻塞和解阻塞線程的方法,這些線程不會(huì)遇到導(dǎo)致已棄用的方法Thread.suspend和Thread.resume無(wú)法用于以下問(wèn)題:由于許可,在調(diào)用park的一個(gè)線程與試圖進(jìn)行unpark的另一個(gè)線程之間的競(jìng)爭(zhēng)將保留生命力。此外,如果調(diào)用者的線程被中斷并且支持超時(shí)版本,則park將返回。 park方法也可能在其他任何時(shí)間出于“無(wú)理由”返回,因此通常必須在循環(huán)中調(diào)用該循環(huán),該循環(huán)在返回時(shí)會(huì)重新檢查條件。從這個(gè)意義上說(shuō),park是對(duì)“繁忙等待”的優(yōu)化,它不會(huì)浪費(fèi)太多的時(shí)間,而必須與unpark配對(duì)才能生效。了解了其作用,我們看看相關(guān)API。

LockSupport.park()

park():除非有許可,否則出于線程調(diào)度目的禁用當(dāng)前線程。如果許可證可用,則將其消耗掉,并立即返回呼叫;否則,將立即返回該呼叫。出于線程調(diào)度的目的,當(dāng)前線程將被禁用,并處于休眠狀態(tài),直到發(fā)生以下三種情況之一:1.其他一些線程以當(dāng)前線程為目標(biāo)調(diào)用unpark()方法2.其他一些線程Threadinterrupt interrupts當(dāng)前線程3.虛假地調(diào)用返回源碼:

public static void park() { UNSAFE.park(false, 0L);}

LockSupport都是調(diào)用的UNSAFE的方法,我們先看看park方法

public class LockSupportMain { public static void main(String[] args) {System.out.println('begin park!');LockSupport.park();System.out.println('end park!'); }}

運(yùn)行結(jié)果:

教你如何使用Java多線程編程LockSupport工具類

我們調(diào)用了park方法,導(dǎo)致Main線程一直被阻塞,一直沒(méi)有結(jié)束,因?yàn)槟J(rèn)的情況下,調(diào)用線程是不持有許可證的,我們?nèi)绾谓鉀Q呢?上面提到過(guò)三個(gè)方式,我們一個(gè)一個(gè)的驗(yàn)證。

1.調(diào)用unpack方法獲得許可

unpack():如果給定線程尚不可用,則使它可用。如果線程在park上被阻止,則它將取消阻止。否則,將確保其對(duì)park的下一次調(diào)用不會(huì)阻塞。如果給定線程尚未啟動(dòng),則不能保證此操作完全無(wú)效。源碼:

public static void unpark(Thread thread) { if (thread != null)UNSAFE.unpark(thread);}

public class LockSupportMain2 { public static void main(String[] args) {System.out.println('begin park!');LockSupport.unpark(Thread.currentThread());LockSupport.park();System.out.println('end park!'); }}

運(yùn)行結(jié)果:

教你如何使用Java多線程編程LockSupport工具類

可以看出,當(dāng)前的線程main已經(jīng)釋放了,沒(méi)有進(jìn)行阻塞,直接運(yùn)行完成了。我們創(chuàng)建一個(gè)線程有Main線程進(jìn)行unpark方法將線程在阻塞的情況下,進(jìn)行運(yùn)行。

public class LockSupportMain3 { public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() { @Override public void run() {System.out.println('begin start thread name: ' + Thread.currentThread().getName() + ' park');LockSupport.park();System.out.println('end start thread name: ' + Thread.currentThread().getName() + ' park'); }};Thread thread = new Thread(runnable);thread.start();Thread.sleep(2000);System.out.println('main thread call unpark');LockSupport.unpark(thread); }}

運(yùn)行結(jié)果:

教你如何使用Java多線程編程LockSupport工具類

運(yùn)行結(jié)果可以看出,其他一些線程以當(dāng)前線程為目標(biāo)調(diào)用unpark()方法可以將線程的park導(dǎo)致阻塞的繼續(xù)運(yùn)行。

2.調(diào)用中斷interrupts方法獲得許可

由于park方法不會(huì)告訴你何種原因返回,所以調(diào)用者需要根據(jù)之前調(diào)用park方法的原因,再次檢查條件是否滿足,如果不能滿足,就還需要調(diào)用park方法

public class LockSupportMain4 { public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() { @Override public void run() {System.out.println('begin start thread name: ' + Thread.currentThread().getName() + ' park');while (!Thread.currentThread().isInterrupted()) { LockSupport.park();}System.out.println('end start thread name: ' + Thread.currentThread().getName() + ' park'); }};Thread thread = new Thread(runnable);thread.start();Thread.sleep(2000);//通過(guò)interrupt方法 讓park阻塞繼續(xù)運(yùn)行thread.interrupt(); }}

運(yùn)行結(jié)果:

教你如何使用Java多線程編程LockSupport工具類

由運(yùn)行可以看出,其他一些線程Threadinterrupt interrupts當(dāng)前線程是可以將park阻塞的線程繼續(xù)運(yùn)行。

parkNanos(long nanos)

parkNanos(long nanos):除非允許使用許可,否則在指定的等待時(shí)間內(nèi)禁用用于線程調(diào)度的當(dāng)前線程。源碼:

public static void parkNanos(long nanos) { if (nanos > 0)UNSAFE.park(false, nanos);}

public class LockSupportMain5 { public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() { @Override public void run() {System.out.println('begin start thread name: ' + Thread.currentThread().getName() + ' park');LockSupport.parkNanos(3_000_000_000L);System.out.println('end start thread name: ' + Thread.currentThread().getName() + ' park'); }};Thread thread = new Thread(runnable);thread.start(); }}

運(yùn)行結(jié)果:

教你如何使用Java多線程編程LockSupport工具類

三秒之后,阻塞三秒之后繼續(xù)運(yùn)行。

park(Object blocker)

park(Object blocker):除非有許可,否則出于線程調(diào)度目的禁用當(dāng)前線程源碼:

public static void park(Object blocker) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(false, 0L); setBlocker(t, null);}

這里的blocker對(duì)象是Thread類中的blocker對(duì)象,代碼如下:

//提供給java.util.concurrent.locks.LockSupport.park的當(dāng)前調(diào)用的參數(shù)。//由(私有)java.util.concurrent.locks.LockSupport.setBlocker設(shè)置使用//java.util.concurrent.locks.LockSupport.getBlocker進(jìn)行訪問(wèn)volatile Object parkBlocker;parkNanos(Object blocker, long nanos)

源碼:

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); }}parkUntil(Object blocker, long deadline)

parkUntil(Object blocker, long deadline):除非指定許可,否則禁用當(dāng)前線程以進(jìn)行線程調(diào)度,直到指定的期限。源碼:

public static void parkUntil(Object blocker, long deadline) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(true, deadline); setBlocker(t, null);}

我們使用java API中的例子看看:

public class LockSupportMain6 { private final AtomicBoolean locked = new AtomicBoolean(false); private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); public void lock() {boolean wasInterrupted = false;Thread current = Thread.currentThread();waiters.add(current);// 不在隊(duì)列中時(shí)先阻塞或無(wú)法獲取鎖定while (waiters.peek() != current ||!locked.compareAndSet(false, true)) { LockSupport.park(this); // 等待時(shí)忽略中斷 如果park方法是因?yàn)楸恢袛喽祷兀瑒t忽略中斷,并且重新設(shè)置中斷標(biāo)記,做個(gè)標(biāo)記 if (Thread.interrupted()) {wasInterrupted = true; }}waiters.remove();// 退出時(shí)重新聲明中斷狀態(tài)if (wasInterrupted) { current.interrupt();} } public void unlock() {locked.set(false);LockSupport.unpark(waiters.peek()); }}

有blocker的可以傳遞給開(kāi)發(fā)人員更多的現(xiàn)場(chǎng)信息,可以查看到當(dāng)前線程的阻塞對(duì)象,方便定位問(wèn)題

到此這篇關(guān)于教你如何使用Java多線程編程-LockSupport工具類的文章就介紹到這了,更多相關(guān)使用java的LockSupport工具類內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲国产欧美精品一区二区三区 | 久久永久视频 | 国产真实强j视频在线观看 国产真实露脸4p视频 | 香蕉视频在线观看网址 | 久久久久99精品成人片三人毛片 | 中文字幕无线码欧美成人 | 国产香港特级一级毛片 | 一道本一区二区三区 | 黄色xxx| 亚洲欧美日韩网站 | 欧美三级毛片 | 国产亚洲精品精品国产亚洲综合 | 成年人小视频在线观看 | 久久国产视频在线观看 | 国产在线精品一区免费香蕉 | 中文字幕在线观看第一页 | 91精品国产三级在线观看 | 国产精品一区高清在线观看 | 精品一区二区三区高清免费不卡 | 精品一区二区三区视频在线观看 | 亚洲自偷| 成年人黄色大片 | 老黄网站在线观看免费 | 亚洲视频一区在线播放 | 一区二区在线精品免费视频 | 黑人特级粗α级毛片 | 成人黄网18免费观看的网站 | 国产一国产a一级毛片 | 亚洲第一毛片 | 一级特一级特色生活片 | 欧美人成在线观看 | 国产系列在线观看 | 91亚洲在线 | 成人夜色香网站在线观看 | 欧美精品一区视频 | 热综合一本伊人久久精品 | 欧美jizz8性欧美18 | a免费在线观看 | 国语性猛交xxxx乱大交 | 手机看片日韩国产 | 国产亚洲精品午夜一区 |