LeetCode 按序打印
第1114题
我们提供了一个类:
public class Foo {
public void one() { print("one"); }
public void two() { print("two"); }
public void three() { print("three"); }
}
三个不同的线程将会共用一个 Foo 实例。
线程 A 将会调用 one() 方法
线程 B 将会调用 two() 方法
线程 C 将会调用 three() 方法
请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。
示例 1:
输入: [1,2,3]
输出: "onetwothree"
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
正确的输出是 "onetwothree"。
示例 2:
输入: [1,3,2]
输出: "onetwothree"
解释:
输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
正确的输出是 "onetwothree"。
注意:
尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/print-in-order
解题思路
- 1.定义一个flag信号量及对象锁lock
- 2.定义三个方法first,second,third用来分别执行A,B,C三个线程,并且在run()前增加限制,执行后更新flag值。比如:first执行条件为flag=0(即C线程执行完),A线程执行完后,flag设置为1表示可以执行B线程了
- 3.通过以上设置,保存了A,B,C线程按顺序执行,这里题目要求从A线程要第一个执行,所以要把flag信号量初始值为0
代码实现
public class Sub1114 {
public static void main(String[] args) throws InterruptedException {
//测试用例字符串
int[] runOrder = new int[]{2, 3, 1};
//生成结果字符串
StringBuffer result = new StringBuffer();
Runnable one = () -> result.append("one");
Runnable two = () -> result.append("two");
Runnable three = () -> result.append("three");
Foo foo = new Foo();
Thread threads[] = new Thread[runOrder.length];
for (int i = 0; i < runOrder.length; ++i) {
Thread thread = null;
if (runOrder[i] == 1) {
thread = new FirstThread(foo, one);
} else if (runOrder[i] == 2) {
thread = new SecondThread(foo, two);
} else if (runOrder[i] == 3) {
thread = new ThirdThread(foo, three);
}
thread.start();
threads[i] = thread;
}
//等侍所有线程执行完
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
//输出结果串
System.out.println(result.toString());
}
}
class FirstThread extends Thread {
Foo foo;
Runnable runnable;
public FirstThread(Foo h2o, Runnable runnable) {
this.foo = h2o;
this.runnable = runnable;
}
@Override
public void run() {
try {
foo.first(runnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class SecondThread extends Thread {
Foo foo;
Runnable runnable;
public SecondThread(Foo h2o, Runnable runnable) {
this.foo = h2o;
this.runnable = runnable;
}
@Override
public void run() {
try {
foo.second(runnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThirdThread extends Thread {
Foo foo;
Runnable runnable;
public ThirdThread(Foo h2o, Runnable runnable) {
this.foo = h2o;
this.runnable = runnable;
}
@Override
public void run() {
try {
foo.third(runnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Foo {
//信号量
private int flag = 0;
//定义Object对象为锁
private Object lock = new Object();
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
synchronized (lock) {
//如果flag不为0则让first线程等待,while循环控制first线程如果不满住条件就一直在while代码块中,防止出现中途跳入,执行下面的代码,其余线程while循环同理
while (flag != 0) {
lock.wait();
}
printFirst.run();
//定义成员变量为 1
flag = 1;
//唤醒其余所有的线程
lock.notifyAll();
}
}
public void second(Runnable printSecond) throws InterruptedException {
synchronized (lock) {
//如果成员变量不为1则让二号等待
while (flag != 1) {
lock.wait();
}
printSecond.run();
//如果成员变量为 1 ,则代表first线程刚执行完,所以执行second,并且改变成员变量为 2
flag = 2;
//唤醒其余所有的线程
lock.notifyAll();
}
}
public void third(Runnable printThird) throws InterruptedException {
synchronized (lock) {
//如果flag不等于2 则一直处于等待的状态
while (flag != 2) {
lock.wait();
}
//如果成员变量为 2 ,则代表second线程刚执行完,所以执行third,并且改变成员变量为 0
printThird.run();
flag = 0;
lock.notifyAll();
}
}
}
资料
LeetCode 按序打印的更多相关文章
- LeetCode:按序打印【1114】
LeetCode:按序打印[1114] 题目描述 我们提供了一个类: 1 2 3 4 5 public class Foo { public void one() { print("on ...
- ERP按序打印问题
按序打印只适合一个机器,不适合主副机模式,主副机模式请勾选同时打印 如果开启主副机模式勾选了按序打印,会造成副机下厨后厨不出单
- LeetCode:打印零与奇偶数【1116】
LeetCode:打印零与奇偶数[1116] 题目描述 假设有这么一个类: class ZeroEvenOdd { public ZeroEvenOdd(int n) { ... } // 构造函数 ...
- Java多线程wait和notify协作,按序打印abc
有一个经典的多线程面试题:启三个线程,按序打印ABC 上代码: package cn.javaBase.study_thread1; class MyRunnable1 implements Runn ...
- LeetCode 从头到尾打印链表
LeetCode 从头到尾打印链表 题目描述 输入一个链表头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 一得之见(Jav ...
- (LeetCode)1114. 按序打印
题目来源:https://leetcode-cn.com/problems/print-in-order/ 我们提供了一个类: public class Foo { public void one( ...
- [LeetCode]1114. 按序打印(并发)
####题目 我们提供了一个类: public class Foo { public void one() { print("one"); } public void tw ...
- LeetCode:交替打印【1115】
LeetCode:交替打印[1115] 题目描述 我们提供一个类: class FooBar { public void foo() { for (int i = 0; i < n; i++) ...
- LeetCode 题解目录
前言 本目录将不断更新记录leetcode的刷题日记. 二叉树 序号 标题 难度 标签 1 108 将有序数组转换为二叉搜索树 简单 树.深度优先搜索 2 538 把二叉搜索树转换为累加树 简单 树 ...
随机推荐
- pod install速度慢解决方案
相信大家已经感受到pod install速度越来越慢了,网上提供了几种解决方案,但是都没有完全解决速度慢的问题. 使用国内镜像的Specs 在pod install时使用命令pod install - ...
- CSS3 斑马条纹.html
hvkhujluhijo hvkhujluhijo hvkhujluhijo hvkhujluhijo hvkhujluhijo <!DOCTYPE html> <html> ...
- Ubuntu 18.04.3 LTS Virtualbox提示“Kernel driver not installed (rc=-1908)”问题修复一例
前两天Ubuntu升级了,重启后启动virtualbox保存 从错误报告上反映出来的问题原因是因为某些内核驱动程序没有经过编译,所以Virtualbox无法正常运行.事实上,在Ubuntu上处理这个问 ...
- Vue全家桶高仿小米商城
大家好,我是河畔一角,时隔半年再次给大家带来一门重量级的实战课程:<Vue全家桶高仿小米商城>,现在很多公司都在参与到商城的构建体系当中,因此掌握一套商城的标准开发体系非常重要:商城的开始 ...
- luogu P2672 推销员 |贪心
题目描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第ii家住户到入口的距离为Si米.由于同一栋 ...
- luogu P1566 加等式
题目描述 对于一个整数集合,我们定义"加等式"如下:集合中的某一个元素可以表示成集合内其他元素之和.如集合{1,2,3}中就有一个加等式:3=1+2,而且3=1+2 和3=2+1是 ...
- 使用dva改造旧项目的数据流方案
前言 最近在给自己的脚手架项目转到TypeScript时,遇到了一些麻烦. 项目之前采用的是react + react-redux + redux-thunk + redux-actions +re ...
- HDU3191-How many paths are there(次短路的长度及其个数)
oooccc1 is a Software Engineer who has to ride to the work place every Monday through Friday. For a ...
- 【React】345- React v16.9 新特性[译]
今天我们发布了 React 16.9.它包含了一些新特性.bug修复以及新的弃用警告,以便与筹备接下来的主要版本. 一.新弃用 重命名 Unsafe 生命周期方法 一年前,我们宣布 unsafe 生命 ...
- 【Redis】270- 你需要知道的那些 redis 数据结构
本文出自「掘金社区」,欢迎戳「阅读原文」链接和作者进行技术交流 ?? 作者简介 世宇,一个喜欢吉他.MDD 摄影.自走棋的工程师,属于饿了么上海物流研发部.目前负责的是网格商圈.代理商基础产线,平时喜 ...