現在有兩種線程,氫 oxygen 和氧 hydrogen,你的目標是組織這兩種線程來產生水分子。
存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。
氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。
這些線程應該三三成組突破屏障并能立即組合產生一個水分子。
你必須保證產生一個水分子所需線程的結合必須發生在下一個水分子產生之前。
換句話說:
如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。
如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。
書寫滿足這些限制條件的氫、氧線程同步代碼。
示例 1:
輸入: "HOH"
輸出: "HHO"
解釋: "HOH" 和 "OHH" 依然都是有效解。
示例 2:
輸入: "OOHHHH"
輸出: "HHOHHO"
解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。
?
限制條件:
輸入字符串的總長將會是 3n, 1 ≤?n?≤ 50;
輸入字符串中的 “H” 總數將會是 2n;
輸入字符串中的 “O” 總數將會是 n。
思路:說白了就是控制個順序。互相pv一下。可以去找一下我寫的操作系統多線程控制。
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簡介
Semaphore,是JDK1.5的java.util.concurrent并發包中提供的一個并發工具類。
所謂Semaphore即 信號量 的意思。
這個叫法并不能很好地表示它的作用,更形象的說法應該是許可證管理器。
其作用在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.
翻譯過來,就是:
Semaphore是一個計數信號量。
從概念上將,Semaphore包含一組許可證。
如果有需要的話,每個acquire()方法都會阻塞,直到獲取一個可用的許可證。
每個release()方法都會釋放持有許可證的線程,并且歸還Semaphore一個可用的許可證。
然而,實際上并沒有真實的許可證對象供線程使用,Semaphore只是對可用的數量進行管理維護。
2.Semaphore方法說明
Semaphore的方法如下:
——Semaphore(permits)
初始化許可證數量的構造函數
——Semaphore(permits,fair)
初始化許可證數量和是否公平模式的構造函數
——isFair()
是否公平模式FIFO
——availablePermits()
獲取當前可用的許可證數量
——acquire()
當前線程嘗試去阻塞的獲取1個許可證。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了1個可用的許可證,則會停止等待,繼續執行。
當前線程被中斷,則會拋出InterruptedException異常,并停止等待,繼續執行。
——acquire(permits)
當前線程嘗試去阻塞的獲取permits個許可證。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了n個可用的許可證,則會停止等待,繼續執行。
當前線程被中斷,則會拋出InterruptedException異常,并停止等待,繼續執行。
——acquierUninterruptibly()
當前線程嘗試去阻塞的獲取1個許可證(不可中斷的)。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了1個可用的許可證,則會停止等待,繼續執行。
——acquireUninterruptibly(permits)
當前線程嘗試去阻塞的獲取permits個許可證。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了n個可用的許可證,則會停止等待,繼續執行。
——tryAcquire()
當前線程嘗試去獲取1個許可證。
此過程是非阻塞的,它只是在方法調用時進行一次嘗試。
如果當前線程獲取了1個可用的許可證,則會停止等待,繼續執行,并返回true。
如果當前線程沒有獲得這個許可證,也會停止等待,繼續執行,并返回false。
——tryAcquire(permits)
當前線程嘗試去獲取permits個許可證。
此過程是非阻塞的,它只是在方法調用時進行一次嘗試。
如果當前線程獲取了permits個可用的許可證,則會停止等待,繼續執行,并返回true。
如果當前線程沒有獲得permits個許可證,也會停止等待,繼續執行,并返回false。
——tryAcquire(timeout,TimeUnit)
當前線程在限定時間內,阻塞的嘗試去獲取1個許可證。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了可用的許可證,則會停止等待,繼續執行,并返回true。
當前線程等待時間timeout超時,則會停止等待,繼續執行,并返回false。
當前線程在timeout時間內被中斷,則會拋出InterruptedException一次,并停止等待,繼續執行。
——tryAcquire(permits,timeout,TimeUnit)
當前線程在限定時間內,阻塞的嘗試去獲取permits個許可證。
此過程是阻塞的,它會一直等待許可證,直到發生以下任意一件事:
當前線程獲取了可用的permits個許可證,則會停止等待,繼續執行,并返回true。
當前線程等待時間timeout超時,則會停止等待,繼續執行,并返回false。
當前線程在timeout時間內被中斷,則會拋出InterruptedException一次,并停止等待,繼續執行。
——release()
當前線程釋放1個可用的許可證。
——release(permits)
當前線程釋放permits個可用的許可證。
——drainPermits()
當前線程獲得剩余的所有可用許可證。
——hasQueuedThreads()
判斷當前Semaphore對象上是否存在正在等待許可證的線程。
——getQueueLength()
獲取當前Semaphore對象上是正在等待許可證的線程數量。
?