LeetCode-1117. H2O 生成(多线程)

2024-06-03 13:32

本文主要是介绍LeetCode-1117. H2O 生成(多线程),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LeetCode 题目描述

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/building-h2o
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

整体思考思路为:

  • 2 个线程并发执行
  • 2 个线程可执行的数量不同(限制线程数量)
  • 2 个线程等待状态互相制约(当前执行的线程需要生成一个水分子后后放行下一组线程)

1.Semaphore + CyclicBarrier

思路:使用信号量控制 2 个线程的访问数量,使用 CyclicBarrier 控制三三成组的执行。

考虑:CyclicBarrier 比较重量级。

class H2O {// 信号量 保证 H2/0 线程执行等待状态,即每次只有 2 个 H 线程、1 个 O 线程可执行private final Semaphore h2 = new Semaphore(2, false);private final Semaphore o = new Semaphore(1, false);// 屏障 ,保证线程三三成组执行private final CyclicBarrier barrier = new CyclicBarrier(3);public H2O() {}public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {h2.acquire();try {barrier.await();} catch (BrokenBarrierException e) {throw new InterruptedException(e.getMessage());}// releaseHydrogen.run() outputs "H". Do not change or remove this line.releaseHydrogen.run();h2.release();}public void oxygen(Runnable releaseOxygen) throws InterruptedException {o.acquire();try {barrier.await();} catch (BrokenBarrierException e) {throw new InterruptedException(e.getMessage());}// releaseOxygen.run() outputs "O". Do not change or remove this line.releaseOxygen.run();o.release();}
}

2. Semaphore + AtomicInteger

思路:使用信号量控制 2 个线程的访问数量,使用 AtomicInteger(CAS) 控制三三成组的执行。

class H2O {// 信号量 保证 H2/0 线程执行等待状态,即每次只有 2 个 H 线程、1 个 O 线程可执行private final Semaphore h2 = new Semaphore(2, false);private final Semaphore o = new Semaphore(1, false);// 屏障 ,保证线程三三成组执行private final AtomicInteger barrier = new AtomicInteger();public H2O() {}public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {h2.acquire();// releaseHydrogen.run() outputs "H". Do not change or remove this line.releaseHydrogen.run();barrier.getAndIncrement();resetBarrier();}public void oxygen(Runnable releaseOxygen) throws InterruptedException {o.acquire();// releaseOxygen.run() outputs "O". Do not change or remove this line.releaseOxygen.run();barrier.getAndIncrement();resetBarrier();}private void resetBarrier() {if (barrier.compareAndSet(3, 0)) { h2.release(2);o.release();}}
}

参考

  • 我的提交记录

这篇关于LeetCode-1117. H2O 生成(多线程)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027122

相关文章

使用python生成固定格式序号的方法详解

《使用python生成固定格式序号的方法详解》这篇文章主要为大家详细介绍了如何使用python生成固定格式序号,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录生成结果验证完整生成代码扩展说明1. 保存到文本文件2. 转换为jsON格式3. 处理特殊序号格式(如带圈数字)4

Java使用Swing生成一个最大公约数计算器

《Java使用Swing生成一个最大公约数计算器》这篇文章主要为大家详细介绍了Java使用Swing生成一个最大公约数计算器的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下... 目录第一步:利用欧几里得算法计算最大公约数欧几里得算法的证明情形 1:b=0情形 2:b>0完成相关代码第二步:加

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

Vue3 如何通过json配置生成查询表单

《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录功能实现背景项目代码案例功能实现背景通过vue3实现后台管理项目一定含有表格功能,通常离不开表单

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅