Leetcode 1114 - 按序打印

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% 的用户

题解反思

这道题主要的解题思路就是采用了三个初始化 permit0 的信号量。这样在程序启动时,刚开始 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

本文首发于「愚一笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值