(多线程)leetcode1117. H2O 生成 认识Java中的PV原语

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

思路:说白了就是控制个顺序。互相pv一下。可以去找一下我写的操作系统多线程控制。

class H2O {private Semaphore h = new Semaphore(2);private Semaphore o = new Semaphore(0);public H2O() {}public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {h.acquire();// releaseHydrogen.run() outputs "H". Do not change or remove this line.releaseHydrogen.run();o.release();}public void oxygen(Runnable releaseOxygen) throws InterruptedException {o.acquire(2);// releaseOxygen.run() outputs "O". Do not change or remove this line.releaseOxygen.run();h.release(2);}
}

Semaphore简介


Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类。

所谓Semaphore即 信号量 的意思。

这个叫法并不能很好地表示它的作用,更形象的说法应该是许可证管理器。

其作用在JDK注释中是这样描述的:

A counting semaphore.
Conceptually, a semaphore maintains a set of permits.
Each {@link #acquire} blocks if necessary until a permit is available, and then takes it.
Each {@link #release} adds a permit, potentially releasing a blocking acquirer.
However, no actual permit objects are used; the {@code Semaphore} just keeps a count of the number available and acts accordingly.

翻译过来,就是:

Semaphore是一个计数信号量。
从概念上将,Semaphore包含一组许可证。
如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证。
每个release()方法都会释放持有许可证的线程,并且归还Semaphore一个可用的许可证。
然而,实际上并没有真实的许可证对象供线程使用,Semaphore只是对可用的数量进行管理维护。
2.Semaphore方法说明
Semaphore的方法如下:

——Semaphore(permits)

初始化许可证数量的构造函数

——Semaphore(permits,fair)

初始化许可证数量和是否公平模式的构造函数

——isFair()

是否公平模式FIFO

——availablePermits()

获取当前可用的许可证数量

——acquire()

当前线程尝试去阻塞的获取1个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了1个可用的许可证,则会停止等待,继续执行。
当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。
——acquire(permits)

当前线程尝试去阻塞的获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了n个可用的许可证,则会停止等待,继续执行。
当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。
——acquierUninterruptibly()

当前线程尝试去阻塞的获取1个许可证(不可中断的)。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了1个可用的许可证,则会停止等待,继续执行。
——acquireUninterruptibly(permits)

当前线程尝试去阻塞的获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了n个可用的许可证,则会停止等待,继续执行。
——tryAcquire()

当前线程尝试去获取1个许可证。

此过程是非阻塞的,它只是在方法调用时进行一次尝试。

如果当前线程获取了1个可用的许可证,则会停止等待,继续执行,并返回true。

如果当前线程没有获得这个许可证,也会停止等待,继续执行,并返回false。

——tryAcquire(permits)

当前线程尝试去获取permits个许可证。

此过程是非阻塞的,它只是在方法调用时进行一次尝试。

如果当前线程获取了permits个可用的许可证,则会停止等待,继续执行,并返回true。

如果当前线程没有获得permits个许可证,也会停止等待,继续执行,并返回false。

——tryAcquire(timeout,TimeUnit)

当前线程在限定时间内,阻塞的尝试去获取1个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了可用的许可证,则会停止等待,继续执行,并返回true。
当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
——tryAcquire(permits,timeout,TimeUnit)

当前线程在限定时间内,阻塞的尝试去获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了可用的permits个许可证,则会停止等待,继续执行,并返回true。
当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
——release()

当前线程释放1个可用的许可证。

——release(permits)

当前线程释放permits个可用的许可证。

——drainPermits()

当前线程获得剩余的所有可用许可证。

——hasQueuedThreads()

判断当前Semaphore对象上是否存在正在等待许可证的线程。

——getQueueLength()

获取当前Semaphore对象上是正在等待许可证的线程数量。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

首元节点

线性表的链式表示和实现: 1.区分一个概念:头结点 头指针 首元节点 首元节点:就是线性表(这里为什么说是线性表,而不说是链表呢?因为我们先来讲清楚首元节点的概念,不涉及指针)当中第…

(多线程)leetcode1195. 交替打印字符串 最简单解法一个变量搞定

编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是: 如果这个数字可以被 3 整除,输出 "fizz"。 如果这个数字可以被 5 整除,输出 "buzz"。 如果这个数字可以同时被 3 和 5 整除,输出 &…

MYSQ产品

前言:MySQL数据库,隶属于MySQLAB公司,总部位于瑞典,后被Oracle收购 MySQLAB公司是由monky及他的两位好朋友创建的,先是被sun公司收购然后被偶尔甲骨文公司收购 MySQL的优点: 1.它的成本是比较低的&#xff…

处理百万级以上的数据提高查询速度的方法

1.应尽量避免在where子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。2.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在where及orderby涉及的列上建立索引。3.应尽量避免在where子句中对字段进行null值判断&#xff0c…

leetcode三道shell题

给定一个文本文件 file.txt&#xff0c;请只打印这个文件中的第十行。 示例: 假设 file.txt 有如下内容&#xff1a; Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 你的脚本应当显示第十行&#xff1a; Line 10 sed -n 10p file.txt 给定一个…

DateFormat(炸窝)

222&#xff1a;DateFormat方法的使用以及功能&#xff1a; java.text.DateFormat是日期或者时间格式化子类的抽象类&#xff0c;作用&#xff1a;可以帮我们完成日期和文本之间的转换&#xff0c;也就是可以在Date对象与String对象之间进行来回转换 格式化&#xff1a; 按照指…

剑指offer:3-7记录

找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1&#xff1a; 输入&#…

计算一个人出生了多少天(炸窝)

223&#xff1a; 小小练习&#xff1a; 请使用日期API来计算一个人出生了多少天&#xff1f; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; public class zixuejava { public static void main(Str…

剑指offer:8-11记录

用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; ["…

mysql命令

Mysql常见的命令总结&#xff1a; mysql服务的退出以及登陆 方式一&#xff1a;通过mysql自带的客户端&#xff0c;只限于root用户 方式二&#xff1a;通过Windows自带的客户端&#xff0c; 登陆&#xff1a;mysql -uroot -p&#xff1b; 退出&#xff1a;exit或者是ctrlc&am…

leetcode343. 整数拆分

给定一个正整数 n&#xff0c;将其拆分为至少两个正整数的和&#xff0c;并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 1: 输入: 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: 10 输出: 36 解释: 10 3 3 4, 3 3 4 36。 思路&#xff1a;动态规…

尚硅谷李老师Mysql基础笔记

数据库的相关概念 一&#xff1a;数据库的好处 1.可以持久化数据到本地 2.结构化查询 二&#xff1a;数据库的常见概念 1.DB&#xff1a;数据库&#xff0c;存储数据的容器 2.DBMS:数据库管理系统&#xff0c;又称为数据库软件或数据库产品&#xff0c;用于创建或者管理数据&…

剑指offer:12-17记录

请设计一个函数&#xff0c;用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始&#xff0c;每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格&#xff0c;那么该路径不能再次进入该格子。例如&#xf…

剑指offer:18-21记录

给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 注意&#xff1a;此题对比原题有改动 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点&#xff0c;那么在调用…

尚硅谷李老师笔记2

一&#xff1a;MySQL的背景 前身是瑞典的一家公司&#xff0c;MySQLAB 08年被sun公司收购 09年sun公司被oracle公司收购 二&#xff1a;MySQL的优点 1.开源&#xff0c;免费&#xff0c;成本低 2.性能高&#xff0c;移植性好 3.体积小&#xff0c;便于安装 三&#xff1a;MyS…

剑指offer:22-25记录

输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表的尾节点是倒数第1个节点。例如&#xff0c;一个链表有6个节点&#xff0c;从头节点开始&#xff0c;它们的值依次是1、2、3、4、5、6。这个链表的倒…

尚硅谷李老师笔记3DQL

一&#xff1a;语法 select 查询列表 from 表名 二&#xff1a;特点 1.查询列表可以是字段&#xff0c;常量&#xff0c;表达式&#xff0c;函数&#xff0c;也可以是多个的组合结果 2.查询结果是一张虚拟表 三&#xff1a;示例 1.查询单个字段 select 字段名 from 表名 2.查…

java 防止表单重复提交

防止表单重复提交&#xff0c;或者是防止按F5 刷新提交表单。 在WEB开发中是经常会碰到这样的问题的。 目前主流的解决方法有以下三种&#xff1a; 1、采用脚本来解决 2、重定向到别的页面 3、使用s:token 标签 由于我是使用S2SH来开发的&#xff0c;所以就选择了第三种方法。 …

贪吃蛇源代码111

#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <time.h> const int H 8; //地图的高 const int L 16; //地图的长 char GameMap[H][L]; //游戏地图 int key; //按键保存 int sum 1, over 0; //蛇…

剑指offer:26-30记录

输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 例如: 给定的树 A: 3 / \ 4 5 / \ 1 2 给定的树 B&#xff1a; 4 / 1 返回 true&#xff0c;因为…