(多线程)leetcode1117. H2O 生成 认识Java中的PV原语
現(xiàn)在有兩種線(xiàn)程,氫 oxygen 和氧 hydrogen,你的目標(biāo)是組織這兩種線(xiàn)程來(lái)產(chǎn)生水分子。
存在一個(gè)屏障(barrier)使得每個(gè)線(xiàn)程必須等候直到一個(gè)完整水分子能夠被產(chǎn)生出來(lái)。
氫和氧線(xiàn)程會(huì)被分別給予 releaseHydrogen 和 releaseOxygen 方法來(lái)允許它們突破屏障。
這些線(xiàn)程應(yīng)該三三成組突破屏障并能立即組合產(chǎn)生一個(gè)水分子。
你必須保證產(chǎn)生一個(gè)水分子所需線(xiàn)程的結(jié)合必須發(fā)生在下一個(gè)水分子產(chǎn)生之前。
換句話(huà)說(shuō):
如果一個(gè)氧線(xiàn)程到達(dá)屏障時(shí)沒(méi)有氫線(xiàn)程到達(dá),它必須等候直到兩個(gè)氫線(xiàn)程到達(dá)。
如果一個(gè)氫線(xiàn)程到達(dá)屏障時(shí)沒(méi)有其它線(xiàn)程到達(dá),它必須等候直到一個(gè)氧線(xiàn)程和另一個(gè)氫線(xiàn)程到達(dá)。
書(shū)寫(xiě)滿(mǎn)足這些限制條件的氫、氧線(xiàn)程同步代碼。
示例 1:
輸入: "HOH"
輸出: "HHO"
解釋: "HOH" 和 "OHH" 依然都是有效解。
示例 2:
輸入: "OOHHHH"
輸出: "HHOHHO"
解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。
?
限制條件:
輸入字符串的總長(zhǎng)將會(huì)是 3n, 1 ≤?n?≤ 50;
輸入字符串中的 “H” 總數(shù)將會(huì)是 2n;
輸入字符串中的 “O” 總數(shù)將會(huì)是 n。
思路:說(shuō)白了就是控制個(gè)順序。互相pv一下??梢匀フ乙幌挛覍?xiě)的操作系統(tǒng)多線(xiàn)程控制。
class H2O {private Semaphore h = new Semaphore(2);private Semaphore o = new Semaphore(0);public H2O() {}public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {h.acquire();// releaseHydrogen.run() outputs "H". Do not change or remove this line.releaseHydrogen.run();o.release();}public void oxygen(Runnable releaseOxygen) throws InterruptedException {o.acquire(2);// releaseOxygen.run() outputs "O". Do not change or remove this line.releaseOxygen.run();h.release(2);} }Semaphore簡(jiǎn)介
Semaphore,是JDK1.5的java.util.concurrent并發(fā)包中提供的一個(gè)并發(fā)工具類(lèi)。
所謂Semaphore即 信號(hào)量 的意思。
這個(gè)叫法并不能很好地表示它的作用,更形象的說(shuō)法應(yīng)該是許可證管理器。
其作用在JDK注釋中是這樣描述的:
A counting semaphore.
Conceptually, a semaphore maintains a set of permits.
Each {@link #acquire} blocks if necessary until a permit is available, and then takes it.
Each {@link #release} adds a permit, potentially releasing a blocking acquirer.
However, no actual permit objects are used; the {@code Semaphore} just keeps a count of the number available and acts accordingly.
翻譯過(guò)來(lái),就是:
Semaphore是一個(gè)計(jì)數(shù)信號(hào)量。
從概念上將,Semaphore包含一組許可證。
如果有需要的話(huà),每個(gè)acquire()方法都會(huì)阻塞,直到獲取一個(gè)可用的許可證。
每個(gè)release()方法都會(huì)釋放持有許可證的線(xiàn)程,并且歸還Semaphore一個(gè)可用的許可證。
然而,實(shí)際上并沒(méi)有真實(shí)的許可證對(duì)象供線(xiàn)程使用,Semaphore只是對(duì)可用的數(shù)量進(jìn)行管理維護(hù)。
2.Semaphore方法說(shuō)明
Semaphore的方法如下:
——Semaphore(permits)
初始化許可證數(shù)量的構(gòu)造函數(shù)
——Semaphore(permits,fair)
初始化許可證數(shù)量和是否公平模式的構(gòu)造函數(shù)
——isFair()
是否公平模式FIFO
——availablePermits()
獲取當(dāng)前可用的許可證數(shù)量
——acquire()
當(dāng)前線(xiàn)程嘗試去阻塞的獲取1個(gè)許可證。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了1個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行。
當(dāng)前線(xiàn)程被中斷,則會(huì)拋出InterruptedException異常,并停止等待,繼續(xù)執(zhí)行。
——acquire(permits)
當(dāng)前線(xiàn)程嘗試去阻塞的獲取permits個(gè)許可證。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了n個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行。
當(dāng)前線(xiàn)程被中斷,則會(huì)拋出InterruptedException異常,并停止等待,繼續(xù)執(zhí)行。
——acquierUninterruptibly()
當(dāng)前線(xiàn)程嘗試去阻塞的獲取1個(gè)許可證(不可中斷的)。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了1個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行。
——acquireUninterruptibly(permits)
當(dāng)前線(xiàn)程嘗試去阻塞的獲取permits個(gè)許可證。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了n個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行。
——tryAcquire()
當(dāng)前線(xiàn)程嘗試去獲取1個(gè)許可證。
此過(guò)程是非阻塞的,它只是在方法調(diào)用時(shí)進(jìn)行一次嘗試。
如果當(dāng)前線(xiàn)程獲取了1個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行,并返回true。
如果當(dāng)前線(xiàn)程沒(méi)有獲得這個(gè)許可證,也會(huì)停止等待,繼續(xù)執(zhí)行,并返回false。
——tryAcquire(permits)
當(dāng)前線(xiàn)程嘗試去獲取permits個(gè)許可證。
此過(guò)程是非阻塞的,它只是在方法調(diào)用時(shí)進(jìn)行一次嘗試。
如果當(dāng)前線(xiàn)程獲取了permits個(gè)可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行,并返回true。
如果當(dāng)前線(xiàn)程沒(méi)有獲得permits個(gè)許可證,也會(huì)停止等待,繼續(xù)執(zhí)行,并返回false。
——tryAcquire(timeout,TimeUnit)
當(dāng)前線(xiàn)程在限定時(shí)間內(nèi),阻塞的嘗試去獲取1個(gè)許可證。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了可用的許可證,則會(huì)停止等待,繼續(xù)執(zhí)行,并返回true。
當(dāng)前線(xiàn)程等待時(shí)間timeout超時(shí),則會(huì)停止等待,繼續(xù)執(zhí)行,并返回false。
當(dāng)前線(xiàn)程在timeout時(shí)間內(nèi)被中斷,則會(huì)拋出InterruptedException一次,并停止等待,繼續(xù)執(zhí)行。
——tryAcquire(permits,timeout,TimeUnit)
當(dāng)前線(xiàn)程在限定時(shí)間內(nèi),阻塞的嘗試去獲取permits個(gè)許可證。
此過(guò)程是阻塞的,它會(huì)一直等待許可證,直到發(fā)生以下任意一件事:
當(dāng)前線(xiàn)程獲取了可用的permits個(gè)許可證,則會(huì)停止等待,繼續(xù)執(zhí)行,并返回true。
當(dāng)前線(xiàn)程等待時(shí)間timeout超時(shí),則會(huì)停止等待,繼續(xù)執(zhí)行,并返回false。
當(dāng)前線(xiàn)程在timeout時(shí)間內(nèi)被中斷,則會(huì)拋出InterruptedException一次,并停止等待,繼續(xù)執(zhí)行。
——release()
當(dāng)前線(xiàn)程釋放1個(gè)可用的許可證。
——release(permits)
當(dāng)前線(xiàn)程釋放permits個(gè)可用的許可證。
——drainPermits()
當(dāng)前線(xiàn)程獲得剩余的所有可用許可證。
——hasQueuedThreads()
判斷當(dāng)前Semaphore對(duì)象上是否存在正在等待許可證的線(xiàn)程。
——getQueueLength()
獲取當(dāng)前Semaphore對(duì)象上是正在等待許可證的線(xiàn)程數(shù)量。
?
總結(jié)
以上是生活随笔為你收集整理的(多线程)leetcode1117. H2O 生成 认识Java中的PV原语的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 深圳旅游景点(深圳旅游必打卡的9个景点!
- 下一篇: java美元兑换,(Java实现) 美元