LeetCode:交替打印【1115】

题目描述

我们提供一个类:

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 次。

示例 1:

输入: n = 1
输出: "foobar"
解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。

示例 2:

输入: n = 2
输出: "foobarfoobar"
解释: "foobar" 将被输出两次。

题目分析

  在解决1114问题按序打印时,我们曾引入了一个Java多线程工具类倒计时器(CountDownLatch),这里要介绍另外一个工具类信号量(Semaphore)。了解更多

  信号量(Semaphore)由一个值和一个指针组成,指针指向等待该信号量的进程。信号量的值表示相应资源的使用情况。信号量S≥0时,S表示可用资源的数量。

  信号量可以被两个操作修改:

  • 执行一次P操作意味着请求分配一个资源,因此S的值减1;当S<0时,表示已经没有可用资源,S的绝对值表示当前等待该资源的进程数。请求者必须等待其他进程释放该类资源,才能继续运行。
  • 执行一次V操作意味着释放一个资源,因此S的值加1;若S<0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。


注意:
信号量的值只能由PV操作来改变。

  我们可利用信号量来描述程序或语句之间的前趋关系

  设有两个并发执行的进程 P1 和 P2。 P1 中有语句 S1;P2 中有语句 S2。我们希望在 S1 执行后再执行 S2。为实现这种前趋关系, 我们只须使进程 P1 和 P2 共享一个公用信号量 S,并赋予其初值为 0,将 signal(S)操作放在 语句 S1 后面;而在 S2 语句前面插入 wait(S)操作,即

  • 在进程 P1 中,用 S1;signal(S);
  • 在进程 P2 中,用 wait(S);S2;

  由于 S 被初始化为 0,这样,若 P2 先执行必定阻塞,只有在进程 P1 执行完 S1;signal(S);操作后使 S 增为 1 时,
P2 进程方能执行语句 S2 成功

  回到题中,先Foo后Bar,添加信号量S2(值为1),先申请资源后再输出Foo,此时S2为0,循环暂停,暂停前需要让Bar有机会输出,所以添加信号量S1(值为0),每当Foo输出后,都释放资源,这样Bar就可以输出了。

Java题解

import java.util.concurrent.Semaphore;

class FooBar {
private Semaphore s1 = new Semaphore(0);
private Semaphore s2 = new Semaphore(1);
private int n; public FooBar(int n) {
this.n = n;
} public void foo(Runnable printFoo) throws InterruptedException { for (int i = 0; i < n; i++) {
// printFoo.run() outputs "foo". Do not change or remove this line.
s2.acquire();
printFoo.run();
s1.release();
}
} public void bar(Runnable printBar) throws InterruptedException { for (int i = 0; i < n; i++) {
// printBar.run() outputs "bar". Do not change or remove this line.
s1.acquire();
printBar.run();
s2.release();
}
}
}

  

LeetCode:交替打印【1115】的更多相关文章

  1. LeetCode:打印零与奇偶数【1116】

    LeetCode:打印零与奇偶数[1116] 题目描述 假设有这么一个类: class ZeroEvenOdd { public ZeroEvenOdd(int n) { ... } // 构造函数 ...

  2. 使用Java线程并发库实现两个线程交替打印的线程题

    背景:是这样的今天在地铁上浏览了以下网页,看到网上一朋友问了一个多线程的问题.晚上闲着没事就决定把它实现出来. 题目: 1.开启两个线程,一个线程打印A-Z,两一个线程打印1-52的数据. 2.实现交 ...

  3. 三个线程ABC,交替打印ABC

    转载与:https://www.cnblogs.com/x_wukong/p/4009709.html 创建3个线程,让其交替打印ABC . 输出如下:  ABCABCABCABC. 方法:使用syn ...

  4. Java 实现多线程切换等待唤醒交替打印奇偶数

    引言 在日常工作生活中,可能会有用时几个人或是很多人干同一件事,在java编程中,同样也会出现类似的情况,多个线程干同样一个活儿,比如火车站买票系统不能多个人买一到的是同一张票,当某个窗口(线程)在卖 ...

  5. 多线程面试题之【三线程按顺序交替打印ABC的方法】

    建立三个线程,线程名字分别为:A.B.C,要求三个线程分别打印自己的线程名字,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印.打印10轮,打印完毕控制台输出字符串:&q ...

  6. 使用Java实现三个线程交替打印0-74

    使用Java实现三个线程交替打印0-74 题目分析 三个线程交替打印,即3个线程是按顺序执行的.一个线程执行完之后,唤醒下一个线程,然后阻塞,等待被该线程的上一个线程唤醒.执行的顺序是一个环装的队列 ...

  7. Thread--两线程交替打印

    package t3.copy; public class ThreadA extends Thread { private Object lock; public ThreadA(Object lo ...

  8. 多线程下,两个线程交替打印0 -100,使用wait()和notify()

    多线程下,两个线程交替打印0 -100,使用wait()和notify() public class ThreadTest{ private static final Object lock = ne ...

  9. java实现线程交替打印1-52和A-Z

    题目: 1.开启两个线程,一个线程打印A-Z,两一个线程打印1-52的数据. 2.实现交替打印,输出结果为12A34B...........5152Z. 3.请用多线程方式实现. 实现思路:通过锁(s ...

随机推荐

  1. ES 调优查询亿级数据毫秒级返回!怎么做到的?--文件系统缓存

    一道面试题的引入: 如果面试的时候碰到这样一个面试题:ElasticSearch(以下简称ES) 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因 ...

  2. Kubernetes 学习7 Pod控制器应用进阶2

    一.容器探测器 1.所谓的容器探测无非就是我们在里面设置了一些探针,或者称之为传感器来获取相应的数据作为判定其存活与否或就绪与否的标准,目前k8s所支持的存活性和就绪性探测方式都是一样的. 2.k8s ...

  3. 几个方便的基于es 的开源文档索引系统

    Apache Tika 比较有名的内容提取工具 FsCrawler 使用java 开发,内部使用了Tika Ambar nodejs,python应用开发,轻量,支持基于docker 的快速部署,同时 ...

  4. Codevs 3002 石子归并 3(DP四边形不等式优化)

    3002 石子归并 3 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次 ...

  5. 【caffe Layer】代码中文注释

    src/caffe/proto/caffe.proto 中LayerParameter部分 // NOTE // Update the next available ID when you add a ...

  6. 读取本地word 浏览器下载(设置编码格式)

    String filePath = "C:\\word\\报告.doc"; BufferedWriter bos = null; BufferedReader bis = null ...

  7. cross socket tcp客户端开发

    cross socket tcp客户端开发 uses Net.SocketAPI, Net.CrossSocket.Base, Net.CrossSocket FCrossTcp: ICrossSoc ...

  8. R scholar和rentrez | NCBI和Google scholar文献数据挖掘

    主要会用到两个R包: rentrez: 'Entrez' in Rscholar: Analyse Citation Data from Google Scholar RISmed 包可以查询 Pub ...

  9. 效率包括了代码的GC 大小与内存大小,执行速度等等。其中执行速度不是关注 的重点

    效率包括了代码的GC 大小与内存大小,执行速度等等.其中执行速度不是关注的重点

  10. 悟空CRM(基于jfinal+vue+ElementUI的前后端分离的开源CRM系统)

    https://www.jfinal.com/share/1591 官网:http://www.5kcrm.com 官网:http://www.72crm.com 论坛:http://bbs.72cr ...