为有牺牲多壮志,敢教日月换新天。

[Java]LeetCode1117. H2O 生成 | Building H2O

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

There are two kinds of threads, oxygen and hydrogen. Your goal is to group these threads to form water molecules. There is a barrier where each thread has to wait until a complete molecule can be formed. Hydrogen and oxygen threads will be given a releaseHydrogen and releaseOxygen method respectfully, which will allow them to pass the barrier. These threads should pass the barrier in groups of three, and they must be able to immediately bond with each other to form a water molecule. You must guarantee that all the threads from one molecule bond before any other threads from the next molecule do.

In other words:

If an oxygen thread arrives at the barrier when no hydrogen threads are present, it has to wait for two hydrogen threads.
If a hydrogen thread arrives at the barrier when no other threads are present, it has to wait for an oxygen thread and another hydrogen thread.
Write synchronization code for oxygen and hydrogen molecules that enforces these constraints.

 

Example 1:

Input: "HOH"
Output: "HHO"
Explanation: "HOH" and "OHH" are also valid answers.
Example 2:

Input: "OOHHHH"
Output: "HHOHHO"
Explanation: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" and "OHHOHH" are also valid answers.
 

Constraints:

Total length of input string will be 3n, where 1 ≤ n ≤ 50.
Total number of H will be 2n in the input string.
Total number of O will be n in the input string.


现在有两种线程,氢 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。


22ms

 1 import java.util.concurrent.Semaphore;
 2 
 3 class H2O {
 4 
 5   private Semaphore s1,s2,s3,s4;
 6     
 7     public H2O() {
 8         s1 = new Semaphore(2); // H线程信号量
 9         s2 = new Semaphore(1); // O线程信号量
10         
11         s3 = new Semaphore(0); // 反应条件信号量
12         s4 = new Semaphore(0); // 反应条件信号量
13     }
14 
15     public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
16         s1.acquire(); // 保证只有2个H线程进入执行
17         s3.release(); // 释放H原子到达信号
18         s4.acquire(); // 等待O原子到达
19         releaseHydrogen.run();
20         s1.release(); // 相当于唤醒1个H线程
21     }
22 
23     public void oxygen(Runnable releaseOxygen) throws InterruptedException {
24         s2.acquire(); // 保证只有1个O线程进入执行
25         s4.release(2); // 释放O原子到达信号,因为有2个H线程等待所以释放2个
26         s3.acquire(2); // 等待H原子到达,2个原因同上
27         releaseOxygen.run();
28         s2.release(); // 相当于唤醒1个O线程
29     }
30 }

23ms

 1 import java.util.concurrent.CountDownLatch;
 2 import java.util.concurrent.Semaphore;
 3 
 4 class H2O {
 5     
 6     private Semaphore semaph1,semaph2,semaph3,semaph4;
 7 
 8     public H2O() {
 9         //用于保证输出两个H和一个O
10         semaph1 = new Semaphore(2); // H线程信号量
11         semaph2 = new Semaphore(1);  // O线程信号量
12         
13         //用于确认一次完整的打印是否已经完成
14         semaph3 = new Semaphore(0);
15         semaph4 = new Semaphore(0);
16     }
17 
18     public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
19         semaph1.acquire();  //等待H原子释放
20         semaph3.release();  // H原子释放完毕信号
21         semaph4.acquire();  // 等待O原子释放H信号
22         // releaseHydrogen.run() outputs "H". Do not change or remove this line.
23         releaseHydrogen.run();
24         semaph1.release();
25         //semaph3.release();
26         
27     }
28 
29     public void oxygen(Runnable releaseOxygen) throws InterruptedException {
30         semaph2.acquire();
31         semaph3.acquire(2); //等待H原子释放完毕信号
32         semaph4.release(2); //释放两个H原子
33         // releaseOxygen.run() outputs "O". Do not change or remove this line.
34         releaseOxygen.run();
35         semaph2.release();
36     }
37 }

25ms

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.ReentrantLock;    
 3 class H2O {
 4         private volatile boolean flag = true;//true表示打印H
 5         private ReentrantLock lock = new ReentrantLock();
 6         private Condition hcondition = lock.newCondition();
 7         private Condition ocondition = lock.newCondition();
 8         private int i = 0;
 9 
10         public H2O() {
11 
12         }
13 
14         public void hydrogen(Runnable releaseHydrogen) throws InterruptedException{
15             try {
16                 lock.lock();
17                 while (!flag) {
18                     hcondition.await();
19                 }
20                 // releaseHydrogen.run() outputs "H". Do not change or remove this line.
21                 releaseHydrogen.run();
22                 i++;
23                 if (i % 2 == 0) {
24                     flag = false;
25                     ocondition.signalAll();
26                 }
27             } finally {
28                 lock.unlock();
29             }
30 
31 
32         }
33 
34         public void oxygen(Runnable releaseOxygen) throws InterruptedException {
35             try {
36                 lock.lock();
37                 while (flag) {
38                     ocondition.await();
39                 }
40                 // releaseOxygen.run() outputs "H". Do not change or remove this line.
41                 releaseOxygen.run();
42                 flag = true;
43                 hcondition.signalAll();
44             } finally {
45                 lock.unlock();
46             }
47         }
48     }

 

posted @ 2019-08-02 16:14  为敢技术  阅读(824)  评论(0编辑  收藏  举报