現(xiàn)在有兩種線程局义,氫 oxygen 和氧 hydrogen鳞上,你的目標(biāo)是組織這兩種線程來(lái)產(chǎn)生水分子袁翁。
存在一個(gè)屏障(barrier)使得每個(gè)線程必須等候直到一個(gè)完整水分子能夠被產(chǎn)生出來(lái)几颜。
氫和氧線程會(huì)被分別給予 releaseHydrogen 和 releaseOxygen 方法來(lái)允許它們突破屏障笼踩。
這些線程應(yīng)該三三成組突破屏障并能立即組合產(chǎn)生一個(gè)水分子获列。
你必須保證產(chǎn)生一個(gè)水分子所需線程的結(jié)合必須發(fā)生在下一個(gè)水分子產(chǎn)生之前谷市。
換句話說(shuō):
如果一個(gè)氧線程到達(dá)屏障時(shí)沒(méi)有氫線程到達(dá),它必須等候直到兩個(gè)氫線程到達(dá)击孩。
如果一個(gè)氫線程到達(dá)屏障時(shí)沒(méi)有其它線程到達(dá)迫悠,它必須等候直到一個(gè)氧線程和另一個(gè)氫線程到達(dá)。
書(shū)寫(xiě)滿足這些限制條件的氫巩梢、氧線程同步代碼创泄。
示例 1:
輸入: "HOH"
輸出: "HHO"
解釋: "HOH" 和 "OHH" 依然都是有效解。
示例 2:
輸入: "OOHHHH"
輸出: "HHOHHO"
解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解括蝠。
寫(xiě)法1:使用volatile修飾變量控制鞠抑, Thread.yield()使線程讓出當(dāng)前時(shí)間片給其他線程執(zhí)行。
class H2O {
public H2O() {
}
volatile int flag = 0;
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
while(flag == 2){
Thread.yield();
}
releaseHydrogen.run();
flag++;
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
// releaseOxygen.run() outputs "O". Do not change or remove this line.
while(flag != 2 ){
Thread.yield();
}
releaseOxygen.run();
flag = 0;
}
}
寫(xiě)法2:使用信號(hào)量Semaphore忌警,acquire(2)要2個(gè)許可證才可以執(zhí)行
class H2O {
public H2O() {
}
private Semaphore h = new Semaphore(2);
private Semaphore o = new Semaphore(0);
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
h.acquire();
releaseHydrogen.run();
o.release();
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
// releaseOxygen.run() outputs "O". Do not change or remove this line.
o.acquire(2);
releaseOxygen.run();
h.release(2);
}
}
寫(xiě)法3:CyclicBarrier可循環(huán)利用的屏障搁拙,await()所有的線程必須同時(shí)到達(dá)柵欄位置,才能繼續(xù)執(zhí)行
class H2O {
private final Semaphore h = new Semaphore(2);
private final Semaphore o = new Semaphore(1);
private final CyclicBarrier c= new CyclicBarrier(3);
public H2O() {
}
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
h.acquire();
try {
c.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
releaseHydrogen.run();
h.release();
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
o.acquire();
try {
c.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
// releaseOxygen.run() outputs "H". Do not change or remove this line.
releaseOxygen.run();
o.release();
}
}