摘要:多線程工具箱之前言這一篇談一下信號(hào)量。信息信息信息信息信息信息信息信息信息信息信息小結(jié)適用于多線程請(qǐng)求數(shù)量資源的場(chǎng)景,但無(wú)法解決單多個(gè)線程對(duì)同一資源訪問(wèn)的競(jìng)爭(zhēng)性訪問(wèn)。在后面我們?cè)谖覀兊亩嗑€程工具箱里面陸續(xù)會(huì)提到。
Java多線程工具箱之Semaphore 前言
這一篇談一下Semaphore:信號(hào)量。
將Semaphore類(lèi)比為為信號(hào)燈,被繼承Runable的線程類(lèi)比為列車(chē):理解信號(hào)量可以參考控制列車(chē)的信號(hào)燈:鐵道上有多個(gè)列車(chē),由信號(hào)燈通知其可用情況。若列車(chē)拿到的信號(hào)燈為綠燈,列車(chē)可以通過(guò),否則列車(chē)不能通過(guò)。
Semaphore用于限制訪問(wèn)線程多于可用資源的場(chǎng)景。
1.1 基本API 構(gòu)造器 Semaphore(int premits)構(gòu)造傳入初始化的允許數(shù)量。
方法 acquire()請(qǐng)求允許,未有有效的允許或者中斷之前,線程將會(huì)阻塞。
方法 release()釋放允許。
1.2 范例在范例中,我們使用一個(gè)機(jī)場(chǎng)請(qǐng)求跑道的模擬程序,機(jī)場(chǎng)有3個(gè)跑道,這個(gè)時(shí)段降落的航班一共有10個(gè)。由于跑道遠(yuǎn)沒(méi)有飛機(jī)的數(shù)量多,因此需要飛機(jī)需要等待可用的跑道資源。這個(gè)程序就是模擬了這個(gè)過(guò)程。
UML App.javaimport java.util.Random; import lombok.extern.java.Log; @Log public class App { static Random ran = new Random(System.currentTimeMillis()); public static void main(String[] args) { Airport ap = new Airport("Baiyun Airport", 3); for (int index = 0; index < 10; index++) { AirPlane plane = new AirPlane(index, String.valueOf(index), String.valueOf(index), ap, ran.nextInt(2) == 0 ? Action.landing : Action.takeOff); Thread thread = new Thread(plane); thread.start(); } } }
import java.util.Arrays; import java.util.concurrent.Semaphore; import lombok.Data; import lombok.extern.java.Log; @Log @Data public class Airport { private String name; private Semaphore semaphore; private Runway[] runways; public Airport(String name, int numberOfRunway) { this.name = name; this.semaphore = new Semaphore(numberOfRunway); runways = new Runway[numberOfRunway]; for (int index = 0; index < numberOfRunway; index++) { Runway currentRunway = new Runway(name, index); runways[index] = currentRunway; } log.info("Airpot is ready :" + Arrays.toString(runways)); } public Runway requestRunway() throws InterruptedException { semaphore.acquire(); while (true) { for (int index = 0; index < runways.length; index++) { Runway runway = runways[index]; if (!runway.isInUse()) { runway.setInUse(true); return runway; } } log.warning("all runway is using, and wait till there is runay release."); } } public void releaseRunway(Runway release) { for (int index = 0; index < runways.length; index++) { Runway runway = runways[index]; if (runway.equals(release)) { runway.setInUse(false); semaphore.release(); } } } }Airplane.java
import java.util.Random; import lombok.Data; import lombok.extern.java.Log; @Data @Log public class AirPlane implements Runnable { private int id; private String name; private String company; private Airport airport; private Action action; private static Random rand = new Random(System.currentTimeMillis()); public AirPlane(int id, String name, String company, Airport airport, Action action) { this.id = id; this.name = name; this.company = company; this.airport = airport; this.action = action; } @Override public void run() { Runway runway = null; try { runway = airport.requestRunway(); log.info(this.toString() + "is using " + runway.toString() + " to " + this.action); int sleepSecond = rand.nextInt(10) * 1000; Thread.sleep(sleepSecond); } catch (InterruptedException e) { log.warning("request runway error"); e.printStackTrace(); } finally { if (airport != null && runway != null) { airport.releaseRunway(runway); } } } }Runway.java
import lombok.Data; @Data public class Runway { private String name; private boolean inUse = false; public Runway(String airportName, int runwayIndex) { this.name = airportName + "_" + runwayIndex; } }運(yùn)行結(jié)果
可以從運(yùn)行結(jié)果中看到,程序運(yùn)行的第一秒,首先幾架的飛機(jī)(線程)都第一時(shí)間的獲得了跑道(資源),而后面幾架飛機(jī)(線程),則在前面的飛機(jī)退出(sleep)跑道(資源)后獲得使用權(quán),進(jìn)行起飛或降落。
Aug 13, 2018 12:56:32 AM online.tangbk.thread.study.semaphore.Airport1.3 Semaphore小結(jié)信息: Airpot is ready :[Runway(name=Baiyun Airport_0, inUse=false), Runway(name=Baiyun Airport_1, inUse=false), Runway(name=Baiyun Airport_2, inUse=false)] Aug 13, 2018 12:56:33 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=1, name=1, company=1, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 1], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=false)]), action=landing)is using Runway(name=Baiyun Airport_1, inUse=true) to landing Aug 13, 2018 12:56:33 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=2, name=2, company=2, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=takeOff)is using Runway(name=Baiyun Airport_2, inUse=true) to takeOff Aug 13, 2018 12:56:33 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=0, name=0, company=0, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 2], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=false), Runway(name=Baiyun Airport_2, inUse=false)]), action=landing)is using Runway(name=Baiyun Airport_0, inUse=true) to landing Aug 13, 2018 12:56:33 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=8, name=8, company=8, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=takeOff)is using Runway(name=Baiyun Airport_1, inUse=true) to takeOff Aug 13, 2018 12:56:35 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=3, name=3, company=3, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=takeOff)is using Runway(name=Baiyun Airport_0, inUse=true) to takeOff Aug 13, 2018 12:56:37 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=4, name=4, company=4, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=landing)is using Runway(name=Baiyun Airport_2, inUse=true) to landing Aug 13, 2018 12:56:40 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=5, name=5, company=5, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=landing)is using Runway(name=Baiyun Airport_2, inUse=true) to landing Aug 13, 2018 12:56:40 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=6, name=6, company=6, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=landing)is using Runway(name=Baiyun Airport_2, inUse=true) to landing Aug 13, 2018 12:56:41 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=7, name=7, company=7, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=takeOff)is using Runway(name=Baiyun Airport_1, inUse=true) to takeOff Aug 13, 2018 12:56:41 AM online.tangbk.thread.study.semaphore.AirPlane run 信息: AirPlane(id=9, name=9, company=9, airport=Airport(name=Baiyun Airport, semaphore=java.util.concurrent.Semaphore@61a09c6b[Permits = 0], runways=[Runway(name=Baiyun Airport_0, inUse=true), Runway(name=Baiyun Airport_1, inUse=true), Runway(name=Baiyun Airport_2, inUse=true)]), action=landing)is using Runway(name=Baiyun Airport_0, inUse=true) to landing
Semaphore適用于多線程請(qǐng)求數(shù)量資源的場(chǎng)景,但無(wú)法解決單多個(gè)線程對(duì)同一資源訪問(wèn)的競(jìng)爭(zhēng)性訪問(wèn)。對(duì)于單一資源的競(jìng)爭(zhēng)性訪問(wèn),依然要使用synchronize關(guān)鍵字或atomic等甚至ReadWriteLock關(guān)鍵字或工具類(lèi)進(jìn)行限制。
在后面我們?cè)谖覀兊亩嗑€程工具箱里面陸續(xù)會(huì)提到。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/76733.html
摘要:當(dāng)線程使用完共享資源后,可以歸還許可,以供其它需要的線程使用。所以,并不會(huì)阻塞調(diào)用線程。立即減少指定數(shù)目的可用許可數(shù)。方法用于將可用許可數(shù)清零,并返回清零前的許可數(shù)六的類(lèi)接口聲明類(lèi)聲明構(gòu)造器接口聲明 showImg(https://segmentfault.com/img/bVbfdnC?w=1920&h=1200); 本文首發(fā)于一世流云的專(zhuān)欄:https://segmentfault...
摘要:整個(gè)包,按照功能可以大致劃分如下鎖框架原子類(lèi)框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見(jiàn)的多線程設(shè)計(jì)模式,設(shè)計(jì)了并發(fā)包,其中包下提供了一系列基礎(chǔ)的鎖工具,用以對(duì)等進(jìn)行補(bǔ)充增強(qiáng)。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專(zhuān)欄:https...
摘要:在每個(gè)線程獲取之前,必須先從信號(hào)量獲取許可。注意,因?yàn)橥瑫r(shí)可能發(fā)生取消,所以返回并不保證有其他線程等待獲取許可。該值僅是估計(jì)的數(shù)字,因?yàn)樵诖朔椒ū闅v內(nèi)部數(shù)據(jù)結(jié)構(gòu)的同時(shí),線程的數(shù)目可能動(dòng)態(tài)地變化。 本人郵箱: 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明網(wǎng)址 http://blog.csdn.net/tianshi_kcogithub: https://github.com/kco1989/kco代碼已經(jīng)全部托...
摘要:前言之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)輔助類(lèi)。而其它線程完成自己的操作后,調(diào)用使計(jì)數(shù)器減。信號(hào)量控制一組線程同時(shí)執(zhí)行。 前言 之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)(輔助類(lèi))。ps:當(dāng)時(shí)覺(jué)得暫時(shí)用不上,認(rèn)為是挺高深的知識(shí)點(diǎn)就沒(méi)去管了.. 在前幾天,朋友發(fā)了一篇比較好的Semaphore文章過(guò)來(lái),然后在瀏覽博客的時(shí)候又發(fā)現(xiàn)面試還會(huì)考,那還是挺重要的知識(shí)點(diǎn)。于是花了點(diǎn)時(shí)間去了解...
摘要:初始時(shí),為,當(dāng)調(diào)用方法時(shí),線程的加,當(dāng)調(diào)用方法時(shí),如果為,則調(diào)用線程進(jìn)入阻塞狀態(tài)。該對(duì)象一般供監(jiān)視診斷工具確定線程受阻塞的原因時(shí)使用。 showImg(https://segmentfault.com/img/remote/1460000016012503); 本文首發(fā)于一世流云的專(zhuān)欄:https://segmentfault.com/blog... 一、LockSupport類(lèi)簡(jiǎn)介...
閱讀 1166·2021-11-24 09:39
閱讀 3668·2021-11-22 13:54
閱讀 2639·2021-10-11 10:59
閱讀 889·2021-09-02 15:40
閱讀 1137·2019-08-30 15:55
閱讀 1108·2019-08-30 13:57
閱讀 2437·2019-08-30 13:17
閱讀 3082·2019-08-29 18:32