LC1117.H2O 生成

1117. H2O 生成

题目描述

现在有两种线程,氧 oxygen 和氢 hydrogen,你的目标是组织这两种线程来产生水分子。

存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来。

氢和氧线程会被分别给予 releaseHydrogenreleaseOxygen 方法来允许它们突破屏障。

这些线程应该三三成组突破屏障并能立即组合产生一个水分子。

你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。

换句话说:

  • 如果一个氧线程到达屏障时没有氢线程到达,它必须等候直到两个氢线程到达。
  • 如果一个氢线程到达屏障时没有其它线程到达,它必须等候直到一个氧线程和另一个氢线程到达。

书写满足这些限制条件的氢、氧线程同步代码。

示例 1:

1
2
3
输入: water = "HOH"
输出: "HHO"
解释: "HOH""OHH" 依然都是有效解。

示例 2:

1
2
3
输入: water = "OOHHHH"
输出: "HHOHHO"
解释: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH""OHHOHH" 依然都是有效解。

提示:

  • 3 * n == water.length
  • 1 <= n <= 20
  • water[i] == 'O' or 'H'
  • 输入字符串 water 中的 ‘H’ 总数将会是 2 * n
  • 输入字符串 water 中的 ‘O’ 总数将会是 n

解题思路

Semaphore(信号量):是一种用来保护一个或多个共享资源访问的计数器。

如果线程想要访问某个资源就必须先获得这个资源的信号量,当信号量内部计数器大于 0 时,获取该信号量会使计数器减一,当信号量的计数器为 0 时,获取该信号量会使线程等待直到该计数器大于 0。

  • hSemaphore:初始值为 2,确保不超过 2 个 hydrogen 可以执行。
  • oSemaphore:初始值为 0,一个 O 对应两个 Hoxygen 执行前要确保有两个 H

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class H2O {
private final Semaphore hSemaphore = new Semaphore(2);
private final Semaphore oSemaphore = new Semaphore(0);
public H2O() {

}

public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
hSemaphore.acquire();
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
releaseHydrogen.run();
oSemaphore.release();
}

public void oxygen(Runnable releaseOxygen) throws InterruptedException {
oSemaphore.acquire(2);
// releaseOxygen.run() outputs "O". Do not change or remove this line.
releaseOxygen.run();
hSemaphore.release(2);
}
}

LC1117.H2O 生成
https://liuyuhe666.github.io/2025/01/20/LC1117-H2O-生成/
作者
Liu Yuhe
发布于
2025年1月20日
许可协议