惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Schneier on Security
Schneier on Security
N
Netflix TechBlog - Medium
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
博客园_首页
S
SegmentFault 最新的问题
H
Help Net Security
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
T
The Blog of Author Tim Ferriss
量子位
GbyAI
GbyAI
M
MIT News - Artificial intelligence
Recorded Future
Recorded Future
P
Privacy & Cybersecurity Law Blog
B
Blog
月光博客
月光博客
博客园 - 聂微东
Vercel News
Vercel News
罗磊的独立博客
腾讯CDC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
Arctic Wolf
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
Blog — PlanetScale
Blog — PlanetScale
L
Lohrmann on Cybersecurity
I
Intezer
小众软件
小众软件
T
The Exploit Database - CXSecurity.com
Jina AI
Jina AI
C
Check Point Blog
AWS News Blog
AWS News Blog
C
Cisco Blogs
Martin Fowler
Martin Fowler
The Last Watchdog
The Last Watchdog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
宝玉的分享
宝玉的分享
S
Security Affairs
大猫的无限游戏
大猫的无限游戏
N
News and Events Feed by Topic
雷峰网
雷峰网
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Hacker News: Front Page
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Full Disclosure
P
Proofpoint News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Security Blog
Microsoft Security Blog

博客园 - 小纸条

模型微调 ruoyiai 启动指南 反向传播 numpy的使用 B 和 B+树 红黑树 ruoyi-vue 梯度下降法 博弈论 离散化 AcWing 907. 区间覆盖 AcWing 906. 区间分组 AcWing 908 最大不相交区间数量 AcWing 905. 区间选点 AcWing 104. 货仓选址 动态规划经典题 窗口函数 1226. 哲学家进餐 1195. 交替打印字符串 1116. 打印零与奇偶数 关联子查询
1117. H2O 生成
小纸条 · 2025-10-28 · via 博客园 - 小纸条

1117. H2O 生成

题目描述

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

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

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

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

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

换句话说:

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

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

示例 1:

输入: "HOH"
输出: "HHO"
解释: "HOH" 和 "OHH" 依然都是有效解。

示例 2:

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

提示:

  • 输入字符串的总长将会是 3n, 1 ≤ n ≤ 50;
  • 输入字符串中的 “H” 总数将会是 2n 。
  • 输入字符串中的 “O” 总数将会是 n 。

解法

Java

class H2O {
    private int hydrogenCount = 0;
    private int oxygenCount = 0;

    public H2O() {
        
    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        synchronized (this) {
            // 等待直到可以组成一个水分子(需要少于2个H)
            while (hydrogenCount == 2) {
                wait();
            }
            
            // 释放氢线程
            releaseHydrogen.run();
            hydrogenCount++;
            
            // 检查是否已经组成一个完整的水分子(2个H + 1个O)
            if (hydrogenCount == 2 && oxygenCount == 1) {
                hydrogenCount = 0;
                oxygenCount = 0;
            }
            
            notifyAll();
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        synchronized (this) {
            // 等待直到可以组成一个水分子(需要少于1个O)
            while (oxygenCount == 1) {
                wait();
            }
            
            // 释放氧线程
            releaseOxygen.run();
            oxygenCount++;
            
            // 检查是否已经组成一个完整的水分子(2个H + 1个O)
            if (hydrogenCount == 2 && oxygenCount == 1) {
                hydrogenCount = 0;
                oxygenCount = 0;
            }
            
            notifyAll();
        }
    }
}

Java

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class H2O {
    private Lock lock = new ReentrantLock();
    private Condition hydrogenCondition = lock.newCondition();
    private Condition oxygenCondition = lock.newCondition();
    
    private volatile int hydrogenCount = 0;
    private volatile int oxygenCount = 0;

    public H2O() {
        
    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        lock.lock();
        try {
            // 等待直到可以添加氢原子(最多2个)
            while (hydrogenCount == 2) {
                hydrogenCondition.await();
            }
            
            // 释放氢原子
            releaseHydrogen.run();
            hydrogenCount++;
            
            // 检查是否形成完整水分子
            checkAndReset();
        } finally {
            lock.unlock();
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        lock.lock();
        try {
            // 等待直到可以添加氧原子(最多1个)
            while (oxygenCount == 1) {
                oxygenCondition.await();
            }
            
            // 释放氧原子
            releaseOxygen.run();
            oxygenCount++;
            
            // 检查是否形成完整水分子
            checkAndReset();
        } finally {
            lock.unlock();
        }
    }
    
    private void checkAndReset() {
        // 如果形成了完整水分子(2个H + 1个O)
        if (hydrogenCount == 2 && oxygenCount == 1) {
            hydrogenCount = 0;
            oxygenCount = 0;
            // 唤醒所有等待的线程
            hydrogenCondition.signalAll();
            oxygenCondition.signalAll();
        }
    }
}

...