LeetCode 1115. 交替打印FooBar
我们提供一个类:
class FooBar {public void foo() {for (int i = 0; i < n; i++) {print("foo");}}public void bar() {for (int i = 0; i < n; i++) {print("bar");}}
}
两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。
请设计修改程序,以确保 “foobar” 被输出 n 次。
方法一:Semaphore
class FooBar {private int n;private Semaphore fooSema = new Semaphore(1);private Semaphore barSema = new Semaphore(0);public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {fooSema.acquire();//值为1的时候,能拿到,执行下面的操作printFoo.run();barSema.release();//释放许可给barSema这个信号量 barSema 的值+1}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {barSema.acquire();//值为1的时候,能拿到,执行下面的操作printBar.run();fooSema.release();//释放许可给fooSema这个信号量 fooSema 的值+1}}}
方法二:Thread.yield()
Thread.yield():使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。
class FooBar {private int n;volatile boolean fooExec = true;//foo可以执行public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; ) {if (fooExec) {printFoo.run();fooExec = false;i++;} else {Thread.yield();}}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; ) {if (!fooExec) {printBar.run();fooExec = true;i++;} else {Thread.yield();}}}
}
方法三:BlockingQueue
class FooBar {private int n;private BlockingQueue<Integer> fooQueue = new LinkedBlockingQueue<Integer>() {{add(0);}};private BlockingQueue<Integer> barQueue = new LinkedBlockingQueue<>();public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {fooQueue.take();printFoo.run();barQueue.add(0);}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {barQueue.take();printBar.run();fooQueue.add(0);}}
}
方法四:Synchronized
class FooBar {private int n;private Object obj = new Object();private volatile boolean fooExec = true;public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {synchronized (obj) {if (!fooExec) {//fooExec为false时,该线程等待,为true的时候执行下面的操作obj.wait();}printFoo.run();fooExec = false;obj.notifyAll();//唤醒其他线程}}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {synchronized (obj) {if (fooExec) {obj.wait();}printBar.run();fooExec = true;obj.notifyAll();}}}
}
LeetCode 1115. 交替打印FooBar相关推荐
- LeetCode 多线程 1115. 交替打印FooBar
1115. 交替打印FooBar Ideas 交替锁的设计,两把锁,foo执行的时候把foo lock acquire,print完了只有把bar lock release,这样foo就得等着,然后b ...
- 1115. 交替打印FooBar
1115. 交替打印FooBar 我们提供一个类: class FooBar {public void foo() {for (int i = 0; i < n; i++) {print(&qu ...
- LeetCode:交替打印【1115】
LeetCode:交替打印[1115] 题目描述 我们提供一个类: class FooBar { public void foo() {for (int i = 0; i < n; i++) { ...
- leet-code 两个线程交替打印FooBar
文章目录 一.题目 二.原理解析 三.完整代码 四.代码优化 五.Java版实现 一.题目 交替打印FooBar 两个不同的线程将会共用一个 FooBar 实例.其中一个线程将会调用foo()方法,另 ...
- Leetcode1115交替打印FooBar
交替打印FooBar 1. 题目描述: 我们提供一个类: class FooBar {public void foo() {for (int i = 0; i < n; i++) {print( ...
- 力扣交替打印FooBar
这道题要注意的是两个线程唤醒和等待的顺序,应为第一个线程会比第二个线程更早结束,所以如果第一个线程已经结束,而第二个线程还在等待被唤醒,那第二个线程会一直等待下去,因此第一个线程要先等待后唤醒,这样他 ...
- 手撕面试题:多个线程交替打印问题
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 第一篇打算总结下阿里最喜欢问的多个线程顺序打印问题,我遇到 ...
- Java常见的面试算法题:实现两个线程交替打印1到100的数
Java常见的面试算法题:实现两个线程交替打印1到100的数 思路: 这是涉及到多个线程打印的问题,一定会用到锁的(synchronized),故这就是一个多线程打印的典型案例. 代码实现: pack ...
- 三个线程交替打印ABC(Condition实现精确通知)
三个线程交替打印ABC: package pc;import java.util.concurrent.locks.Condition; import java.util.concurrent.loc ...
最新文章
- 在VMware Workstation上安装Ubuntu 16.04 Server操作系统
- JS操作Excel读取和写入(模板操作)
- c c 语言程序设计同步,第一部分C语言程序设计C语言程序设计同步练习答案.PDF...
- MyBatis子查询
- 商品详细信息的代码html_Web前端,你该有的代码规范
- maven集成spring_Maven集成测试和Spring Restful Services
- 来电振铃时按音量键静音
- ENVI提取植被指数(NDVI)的两种方法
- Java音频格式转换,支持amr、aud、slk、silk转成mp3
- 108-周跳探测之GF
- python海龟绘图代码大全-Python中的高级turtle(海龟)作图
- tp6使用workman实现定时任务
- AAAI论文摘要【知识图谱补全】:A Survey on knowledge Graphs:Representation,Acquisition and Application
- 关于大数据相关的问答汇总,持续更新中~
- 2019 拼多多校招第三题sum 服务端研发工程师
- flac文件转wav_WAV文件真的比FLAC更好吗?
- oul可以用作c语言常量吗,STL chips
- dell灵越笔记本后盖怎么拆_戴尔灵越5584笔记本按键拆卸、安装教程
- 文本(文章内容)编辑器(CMS管理)
- 使用CAS框架快速实现单点登录
热门文章
- 对一个存储过程语法的解读
- delphi IOS 通知 TNotification
- 使用Ext Designer 设计简单计算器
- 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...
- beta阶段——项目复审
- Python基础【day03】:字典(一)
- C语言实现栈的进栈与出栈、输出栈顶元素、元素个数、销毁栈
- 江苏大学考研885程序设计 - 谭浩强课后习题
- 基于springboot+thymeleaf+mybatis的员工管理系统 —— 登录与注册
- RSA加密算法【手把手解释】