此文首发于我的个人博客:LeetCode 1117. Building H2O --Java解法–多线程保证执行顺序–AtomicInteger — zhang0peter的个人博客


LeetCode题解文章分类:LeetCode题解
LeetCode 所有题目总结:LeetCode 所有题目总结


题目地址:Building H2O - LeetCode


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 releaseHydrogen and releaseOxygen methods respectively, 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.
We don’t have to worry about matching the threads up explicitly; that is, the threads do not necessarily know which other threads they are paired up with. The key is just that threads pass the barrier in complete sets; thus, if we examine the sequence of threads that bond and divide them into groups of three, each group should contain one oxygen and two hydrogen threads.

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 ≤ 20.
Total number of H will be 2n in the input string.
Total number of O will be n in the input string.


这道题目的意思是多线程情况下如何保证代码执行的顺序,是一道经典的多线程的题目。

比较容易想到使用信号量:Semaphore,但问题的难点在于怎样使用信号量保证一致性。
经过思考,我觉得没必要使用信号量,使用 AtomicInteger 就够用了,最终代码如下。

Java解法如下:

class H2O {private final AtomicInteger h2o = new AtomicInteger();public H2O() {}public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {synchronized (h2o) {// if already release two Hydrogen, wait for Oxygen releasewhile (h2o.get() == 2) {h2o.wait();}h2o.addAndGet(1);// releaseHydrogen.run() outputs "H". Do not change or remove this line.releaseHydrogen.run();h2o.notifyAll();}}public void oxygen(Runnable releaseOxygen) throws InterruptedException {synchronized (h2o) {// if already release Oxygen, wait for Hydrogen releasewhile (h2o.get() < 0) {h2o.wait();}h2o.addAndGet(-2);// releaseOxygen.run() outputs "O". Do not change or remove this line.releaseOxygen.run();h2o.notifyAll();}}

LeetCode1117. Building H2O --Java解法--多线程保证执行顺序--AtomicInteger相关推荐

  1. Java笔记——Java代码块的执行顺序

    Java代码块的执行顺序 Java程序中代码块的执行顺序对于学习Java的人来说是必不可少需要掌握的. 代码块 在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为: 局 ...

  2. Java基础之代码执行顺序深入解析

    Java基础之代码执行顺序深入解析 结合实例代码分析: public class demo6 {public static void main(String[] args) {new Son();Sy ...

  3. java中this_夯实Java基础系列7:一文读懂Java 代码块和执行顺序

    目录 #java中的构造方法 #构造方法简介 #构造方法实例 #例-1 #例-2 #java中的几种构造方法详解 #普通构造方法 #默认构造方法 #重载构造方法 #java子类构造方法调用父类构造方法 ...

  4. c语言中多线程的执行顺序,ReentrantLock实现 多线程顺序执行任务

    题目摘自:偏头痛杨 最近看了这位博主的文章 写的挺好的 跟着里面的线程 温习了一遍 结尾处有道题算是复习巩固吧 我是用ReentrantLock实现的 而不是synchronized 题目:使用3个线 ...

  5. java的for的执行顺序_对java for 循环执行顺序的详解

    如下所示: for(表达式1;表达式2;表达式3) { //循环体 } 先执行"表达式1",再进行"表达式2"的判断,判断为真则执行 "循环体&quo ...

  6. 关于Java中try-catch-finally-return的执行顺序

    1.try块中没有抛出异常,try.catch和finally块中都有return语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static int ...

  7. java程序基础——SQL执行顺序

    SQL执行顺序 1.from 2.join 3.on 4.where 5. group by(开始使用select中的别名,后面的语句中都可 以使用) 6.avg,sum.... 7.having 8 ...

  8. Java Script 多线程并发执行与异步执行浅析

    众所周知,JS是单线程运行机制,但是当我们在使用AJAX请求时会有async选项,来实现异步. 那么小编今天来简单的说一下关于JS的异步到底是怎么实现的. 我们先测试这样一段代码: self.setI ...

  9. Java中构造方法的执行顺序

    2019独角兽企业重金招聘Python工程师标准>>> 一.先执行内部静态对象的构造方法,如果有多个按定义的先后顺序执行:静态对象在构造的时候也是也先执行其内部的静态对象. 二.再调 ...

最新文章

  1. idea maven打jar包_Dev 日志 | 如何将 jar 包发布到 Maven 中央仓库
  2. html 流动效果,html5 canvas流动的海浪特效
  3. <%=(String)request.getAttribute(““) %>的作用是什么
  4. GridView控件 72变(一)
  5. ESLint + lint-staged 禁用老项目中的es6
  6. python自定义包的发布与安装
  7. win10为单个网卡配置多个IP地址
  8. python之 ffmpeg合并ts视频为mp4视频
  9. C# Key Value列表
  10. 极狐GitLab CI/CD 测试题
  11. 系统地学习3D建模!教你零基础入门
  12. 一款压缩率达到五倍以上的免费gif压缩网站
  13. 前端和后端哪个工资高?前端工程师的工资,比后端低吗?
  14. 用 Python 实现资本资产定价模型
  15. [附源码]java毕业设计网上书店系统
  16. 【MindSpore】【数据集】数据集内数据获取失败导致迭代器退出
  17. GVIM/VIM常用快捷操作(更新中)
  18. 实验五 大学数据库系统中,使用游标编写存储过程,输入学号查询成绩
  19. qemu stm32环境搭建教程
  20. 「传统的互联网模式」呈现的是粗放式的,野蛮生长的状态

热门文章

  1. RDKit支持PostgreSQL配置
  2. python安装包的方法与图解_Python下载和安装过程详解(包含所有平台)
  3. 双稳态电路的两个稳定状态是什么_振荡器基础4——什么是多谐振荡器(又称:弛张振荡器)?...
  4. R绘制Rank-abundance曲线
  5. Science Bulletin:崔杰组发表了深浅海软甲纲动物比较病毒组学分析成果
  6. numpy使用np.set_printoptions函数抑制numpy数组输出结果使用科学计数法进行显示(suppressing scientific notation in numpy array)
  7. pandas使用pad函数向dataframe特定数据列的每个字符串添加前置(前缀)补齐字符或者字符串、向所有字符串的左侧填充、直到宽度达到指定要求(left padding)
  8. R语言apriori算法进行关联规则挖掘(限制规则的左侧或者右侧的内容进行具体规则挖掘)、使用subset函数进一步筛选生成的规则去除左侧规则中的冗余信息、获取更独特的有新意的关联规则
  9. 学习笔记:数据分析和处理(ML计算模型前的预处理)——持续更新
  10. 学习笔记:Model Diagnostics-模型诊断(线性回归)