网站首页 > 技术文章 正文
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"。
- 注意*: 尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。你看到的输入格式主要是为了确保测试的全面性。
提交答案
class Foo {
public Foo() {}
private Semaphore first = new Semaphore(0);
private Semaphore second = new Semaphore(0);
private Semaphore third = new Semaphore(0);
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
first.release();
second.release();
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
second.acquire();
printSecond.run();
second.release();
third.release();
}
public void third(Runnable printThird) throws InterruptedException {
// printThird.run() outputs "third". Do not change or remove this line.
third.acquire();
printThird.run();
third.release();
}
}
执行用时: 12 ms , 在所有 Java 提交中击败了 74.80% 的用户
内存消耗: 39.3 MB , 在所有 Java 提交中击败了 5.60% 的用户
题解反思
这道题主要的解题思路就是采用了三个初始化 permit 为 0 的信号量。这样在程序启动时,刚开始 second.acquire() 和 third.acquire() 均不会获取到线程资源,直到 first 执行完 run() 方法后,才会释放第二个信号量,这时 second.acquire() 才能获取到信号量,继而 printSecond.run() ,之后 second 又会释放第三个信号量,同样这时 third.acquire() 才能够获取到信号量,从而成功执行 printThird.run(),通过这样的方式,保证了线程的按许执行。
这里贴一下 Java 中信号量 Semaphore 的官方接口文档,可供查阅。https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/Semaphore.html
在并发问题中,他们都有一个共同的特征,即:多个线程/进程之间共享某些资源,从而导致并发访问时的冲突。由于在程序中无法消除所有对共享资源的依赖,在这种情况下,防止并发问题就变成了共享资源的协调问题了。因此,解决这类问题其中最核心的思想就是要保证共享资源在某个时刻只能有一个线程/进程访问,也就是确保系统中关键代码的独占性,这样就可以防止程序进入不一致的状态。
最后,再推荐一篇信号量相关的教程。 Semaphores in Java
本文首发于「愚一笔记」
猜你喜欢
- 2024-11-12 有关条码打印软件数据对象类型的简单介绍
- 2024-11-12 中琅珠宝标签打印软件在珠宝标签方面的应用
- 2024-11-12 OracleP6机场工程进度控制系列18:总进度综合管控信息平台(上)
- 2024-11-12 希雅途智能仓储系统 之 条码/二维码打印功能
- 2024-11-12 中琅珠宝标签制作打印软件 珠宝标签打印教程
- 2024-11-12 中琅商品标签打印软件 中琅标签制作软件
- 2024-11-12 SQL语句打印、性能分析框架 sqlplus打印执行sql
- 2024-11-12 工业条码打印软件Leantek,叫板BarTender
- 2024-11-12 中琅条码打印软件数据库连接详解 中琅条码打印软件怎么安装
- 2024-11-12 Labeljoy 6.24.03.29 标签打印软件
你 发表评论:
欢迎- 615℃几个Oracle空值处理函数 oracle处理null值的函数
- 607℃Oracle分析函数之Lag和Lead()使用
- 595℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 592℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 586℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 580℃【数据统计分析】详解Oracle分组函数之CUBE
- 569℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 560℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- PageHelper - 最方便的 MyBatis 分页插件
- 面试二:pagehelper是怎么实现分页的,
- MyBatis如何实现分页查询?(mybatis-plus分页查询)
- SpringBoot 各种分页查询方式详解(全网最全)
- 如何在Linux上运行exe文件,怎么用linux运行windows软件
- 快速了解hive(快速了解美国50个州)
- Python 中的 pyodbc 库(pydbclib)
- Linux搭建Weblogic集群(linux weblogic部署项目步骤)
- 「DM专栏」DMDSC共享集群之部署(一)——共享存储配置
- 故障分析 | MySQL 派生表优化(mysql pipe)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)