我们提供一个类:

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相关推荐

  1. LeetCode 多线程 1115. 交替打印FooBar

    1115. 交替打印FooBar Ideas 交替锁的设计,两把锁,foo执行的时候把foo lock acquire,print完了只有把bar lock release,这样foo就得等着,然后b ...

  2. 1115. 交替打印FooBar

    1115. 交替打印FooBar 我们提供一个类: class FooBar {public void foo() {for (int i = 0; i < n; i++) {print(&qu ...

  3. LeetCode:交替打印【1115】

    LeetCode:交替打印[1115] 题目描述 我们提供一个类: class FooBar { public void foo() {for (int i = 0; i < n; i++) { ...

  4. leet-code 两个线程交替打印FooBar

    文章目录 一.题目 二.原理解析 三.完整代码 四.代码优化 五.Java版实现 一.题目 交替打印FooBar 两个不同的线程将会共用一个 FooBar 实例.其中一个线程将会调用foo()方法,另 ...

  5. Leetcode1115交替打印FooBar

    交替打印FooBar 1. 题目描述: 我们提供一个类: class FooBar {public void foo() {for (int i = 0; i < n; i++) {print( ...

  6. 力扣交替打印FooBar

    这道题要注意的是两个线程唤醒和等待的顺序,应为第一个线程会比第二个线程更早结束,所以如果第一个线程已经结束,而第二个线程还在等待被唤醒,那第二个线程会一直等待下去,因此第一个线程要先等待后唤醒,这样他 ...

  7. 手撕面试题:多个线程交替打印问题

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 第一篇打算总结下阿里最喜欢问的多个线程顺序打印问题,我遇到 ...

  8. Java常见的面试算法题:实现两个线程交替打印1到100的数

    Java常见的面试算法题:实现两个线程交替打印1到100的数 思路: 这是涉及到多个线程打印的问题,一定会用到锁的(synchronized),故这就是一个多线程打印的典型案例. 代码实现: pack ...

  9. 三个线程交替打印ABC(Condition实现精确通知)

    三个线程交替打印ABC: package pc;import java.util.concurrent.locks.Condition; import java.util.concurrent.loc ...

最新文章

  1. 在VMware Workstation上安装Ubuntu 16.04 Server操作系统
  2. JS操作Excel读取和写入(模板操作)
  3. c c 语言程序设计同步,第一部分C语言程序设计C语言程序设计同步练习答案.PDF...
  4. MyBatis子查询
  5. 商品详细信息的代码html_Web前端,你该有的代码规范
  6. maven集成spring_Maven集成测试和Spring Restful Services
  7. 来电振铃时按音量键静音
  8. ENVI提取植被指数(NDVI)的两种方法
  9. Java音频格式转换,支持amr、aud、slk、silk转成mp3
  10. 108-周跳探测之GF
  11. python海龟绘图代码大全-Python中的高级turtle(海龟)作图
  12. tp6使用workman实现定时任务
  13. AAAI论文摘要【知识图谱补全】:A Survey on knowledge Graphs:Representation,Acquisition and Application
  14. 关于大数据相关的问答汇总,持续更新中~
  15. 2019 拼多多校招第三题sum 服务端研发工程师
  16. flac文件转wav_WAV文件真的比FLAC更好吗?
  17. oul可以用作c语言常量吗,STL chips
  18. dell灵越笔记本后盖怎么拆_戴尔灵越5584笔记本按键拆卸、安装教程
  19. 文本(文章内容)编辑器(CMS管理)
  20. 使用CAS框架快速实现单点登录

热门文章

  1. 对一个存储过程语法的解读
  2. delphi IOS 通知 TNotification
  3. 使用Ext Designer 设计简单计算器
  4. 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...
  5. beta阶段——项目复审
  6. Python基础【day03】:字典(一)
  7. C语言实现栈的进栈与出栈、输出栈顶元素、元素个数、销毁栈
  8. 江苏大学考研885程序设计 - 谭浩强课后习题
  9. 基于springboot+thymeleaf+mybatis的员工管理系统 —— 登录与注册
  10. RSA加密算法【手把手解释】