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. 上传图片,点击触发隐藏得file

    编辑一个div   将其宽高设定好 给其背景颜色 div class="form-group"> <label class="col-sm-2 control ...

  2. Hive 实现update和delete(转载)

    原文链接:https://blog.csdn.net/xueyao0201/article/details/79387647 因为业务要求,需要对Hive表进行delete,在官网查询后,发现upda ...

  3. 自定义mvc增删改查

    对t_mvc_book表的增删改查 导入jar包 BaseDao package com.hmc.util; import java.lang.reflect.Field; import java.s ...

  4. 留言板welcome here friends!

    欢迎留言!!! 另附本人信息栏 \(cnblogs\): ShineEternal \(洛谷\):vercont \(CSDN\) \(blog\): ShineEternal \(github\) ...

  5. 34、spark1.5.1

    一.Spark 1.4.x的新特性 1.Spark Core 1.1 提供REST API供外界开发者获取Spark内部的各种信息(jobs / stages / tasks / storage in ...

  6. 最大字段和&洛谷11月月赛DIV2 T1

    蒟蒻只能打一打DIV2的基础题 太卑微了 这道题的本质其实是再建一个数组,如果s串i位置是0那么就给a[i]赋值为1,表示要累加个数,如果是1那么就把a[i]赋值为-1,表示个数减一,最后求最大子段和 ...

  7. docker 随笔记录

    .docker 固定网络ip地址,启动 Docker的时候,用 --network 参数,可以指定网络类型 eg:docker run -itd --name test1 --network brid ...

  8. git提交报错:Updates were rejected because the tip of your current branch is behind

    提交代码push时报错:上网查询了一下解决办法有很多种,1.使用强制push的方法:(上网查询说这种会使远程修改丢失,一般是不可取的,尤其是多人协作开发的时候.) git push -u origin ...

  9. 【转】Android检查手机是否被root

    目前来说Android平台并没有提供能够root检查的工具.但是我们可以通过两种方式来判断 手机里面是否有su文件 这个su文件是不是能够执行 但是这两种检查方式都存在缺点. 第一种存在误测和漏测的情 ...

  10. 2019年ArcGIS规划专业专项培训(四天)

    2019年ArcGIS规划专业专项培训(四天) 商务合作,科技咨询,版权转让:向日葵,135-4855__4328,xiexiaokui#qq.com   第一天:GIS入门 第一章 GIS概述及其应 ...