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 把二叉搜索树转换为累加树 简单 树 ...
随机推荐
- vue使用tips
1. native修饰符可以用来绑定原生事件 2. destroyed在列表重渲染时,销毁的列表项会调用. 3. 并不是所有的数据都适合放入vuex 4. 子组件mounted先于父组件发生. 5. ...
- 循环神经网络(RNN)的改进——长短期记忆LSTM
一:vanilla RNN 使用机器学习技术处理输入为基于时间的序列或者可以转化为基于时间的序列的问题时,我们可以对每个时间步采用递归公式,如下,We can process a sequence ...
- 有趣的css3实战案例剖析—(背景动态渐变)
对于css3的学习,更多的是在于对新特性和基础理论的熟悉,这篇文章通过一个案例带领大家了解css3里一些理论知识,也将一些技巧加以总结,从而提高大家的开发效率: 本次案例为(背景颜色渐变),运用css ...
- 这是一个测试 hello world
第一次写博客,冒着生命危险尝试一下,发说说 搞了半天,发现原创文章在随笔发,我以为在文章目录发,白白在文章那里建了分类,太难了吧我
- luogu P2947 [USACO09MAR]向右看齐Look Up |单调队列
题目描述 Farmer John's N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again stan ...
- XML与JSON解析
[XML简介] XML在线校验工具: http://tool.oschina.net/codeformat/xml 可扩展标记语言(EXtensible Markup Language) 一种标记语言 ...
- 2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)
题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 题解: 树的直径可以通过两次 dfs() 的方法求得.换句话说,到任意点最远的 ...
- CoderForces-913D
You are preparing for an exam on scheduling theory. The exam will last for exactly Tmilliseconds and ...
- TypeScript - 泛型
什么是泛型 官方是这样介绍的: 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵 ...
- 原生js 复制内容到剪切板
代码: function copyHandle(content){ let copy = (e)=>{ e.preventDefault() e.clipboardData.setData('t ...