第1117题

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

解题思路

  • 1.设定一个h信息号
  • 2.每生成一个h,当h等于2的时候则进入等待o。否则生成氢气并且h自加1。
  • 3.每生成一个o,当h小于2的时候则进入等侍h。否则生成o并且h清0,重新开始生成一个水份子
  • 4.注意Runnable和Thread的区别,实现了Runnable接口,无法启动线程,必须依托其他类或线程

代码实现

public class Sub1117 {
public static void main(String[] args) throws InterruptedException {
//测试用例字符串
String test = "HOHOHHOOHOHHHHHOHHHOH"; //生成结果字符串
StringBuffer result = new StringBuffer(); //注意:创建的Runnable任务,无法启动线程,必须依托其他类或线程启动
//创建生成氧气任务
Runnable releaseHydrogen = () -> result.append("H"); //创建生成氧气任务
Runnable releaseOxygen = () -> result.append("O"); //保存线程数组
Thread threads[] = new Thread[test.length()]; H2O h2o = new H2O();
for (int i = 0; i < test.length(); ++i) {
Thread thread = null;
//根据获得的字符调用相应的氧气或氢气线程
if (test.charAt(i) == 'O') {
thread = new OGenerator(h2o, releaseOxygen);
} else if (test.charAt(i) == 'H') {
thread = new HGenerator(h2o, releaseHydrogen);
}
//开始线程
thread.start();
//保存到线程数组
threads[i] = thread;
} //等侍所有线程执行完
for (int i = 0; i < threads.length; i++) {
threads[i].join();
} //输出结果串
System.out.println(result.toString());
}
} //氢气生成线程
class HGenerator extends Thread {
H2O h2o;
Runnable releaseHydrogen; public HGenerator(H2O h2o, Runnable releaseHydrogen) {
this.h2o = h2o;
this.releaseHydrogen = releaseHydrogen;
} @Override
public void run() {
try {
h2o.hydrogen(releaseHydrogen);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} //氧气生成线程
class OGenerator extends Thread {
H2O h2o;
Runnable releaseOxygen; public OGenerator(H2O h2o, Runnable releaseOxygen) {
this.h2o = h2o;
this.releaseOxygen = releaseOxygen;
} @Override
public void run() {
try {
h2o.oxygen(releaseOxygen);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} class H2O {
public H2O() {
} int h = 0; public synchronized void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
while (h == 2) {
this.wait();
}
releaseHydrogen.run();
++h;
this.notify();
} public synchronized void oxygen(Runnable releaseOxygen) throws InterruptedException {
while (h < 2) {
this.wait();
}
releaseOxygen.run();
h = 0;
this.notify();
}
}

资料

LeetCode H2O 生成的更多相关文章

  1. Leetcode 22.生成括号对数

    生成括号对数 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "( ...

  2. LeetCode 题解目录

    前言 本目录将不断更新记录leetcode的刷题日记. 二叉树 序号 标题 难度 标签 1 108 将有序数组转换为二叉搜索树 简单 树.深度优先搜索 2 538 把二叉搜索树转换为累加树 简单 树 ...

  3. leetcode难题

    4 寻找两个有序数组的中位数       35.9% 困难     10 正则表达式匹配       24.6% 困难     23 合并K个排序链表       47.4% 困难     25 K ...

  4. Oracle 11g数据库详解(2)

    FAILED_LOGIN_ATTEMPTS 用于指定连续登陆失败的最大次数 达到最大次数后,用户会被锁定,登陆时提示ORA-28000 UNLIMITED为不限制 精确无误差 是 实时 PASSWOR ...

  5. [LeetCode] Generate Parentheses 生成括号

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  6. [LeetCode] Generate Random Point in a Circle 生成圆中的随机点

    Given the radius and x-y positions of the center of a circle, write a function randPoint which gener ...

  7. leetcode 22括号生成

    非常好的一道题.一开始的思想是这样的,先把n对括号按照某一顺序生成一个string,然后用全排列算法生成所有可能,然后利用stack写一段判断括号是否匹配的字符串,匹配的假如结果中.不过会超时.因为全 ...

  8. [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题

    一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer上的一道例题入手,小谈一下这种类型题目的解法. 二.上手 最典型的permutation题目是这样的 ...

  9. “全排列”问题系列(一)[LeetCode] - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题

    转:http://www.cnblogs.com/felixfang/p/3705754.html 一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer ...

随机推荐

  1. JS获取当前完整的url地址以及参数的方法

    javascript 获取当前 URL 参数的两种方法: //返回的是字符串形式的参数,例如:class_id=3&id=2& function getUrlArgStr(){ var ...

  2. (转)oracle视图详解

    Oracle视图详解   一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的.视图只有逻辑定义.每次使用的时候,只是重新执 ...

  3. 2019沈阳icpc网络赛H德州扑克

    题面:https://nanti.jisuanke.com/t/41408 题意:A,2,3,4,5,6,7,8,9,10,J,Q,K,13张牌,无花色之分,val为1~13. 给n个人名+n个牌,输 ...

  4. CoderForces985F-Isomorphic Strings

    F. Isomorphic Strings time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

  5. 通过Centreon监控apache、MySQL、Hadoop服务状态

    在上面的章节中,只是简单介绍了Centreon的几个基础监控项,例如添加主机.服务等,这些对于一个监控系统来说是远远不够的,本节将重点介绍对一些扩展服务的监控,也就是对一些常见应用的监控. 一. Na ...

  6. 从多谐振荡器详细解析到555定时器基本电路(控制LED闪烁)

    在学期末,笔者参加了学校的电工实习,前六天做都很快,但是今天要做一个关于555多谐振荡器的LED闪烁电路,由于笔者没有提前准备,导致今天就算把电路搭建出来也不懂具体原理,耗费了不少时间,所以我打算专门 ...

  7. Java垃圾回收机制你还不明白?一线大厂面试必问的!

    什么是自动垃圾回收? 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制. 所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未 ...

  8. 你不会还在用这8个错误的SQL写法吧?

    1.LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引 ...

  9. 想要金九银十面试通关,不懂 Java多线程肯定是不行的!

    作者 | 纳达丶无忌 如果对什么是线程.什么是进程仍存有疑惑,请先 Google 之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用 CPU 的资源,因为所有的多线程代码都 ...

  10. webpack实践(四)- html-webpack-plugin

    webpack系列博客中代码均在github上:https://github.com/JEmbrace/webpack-practice <webpack实践(一)- 先入个门> < ...