春招打卡d3n04-leetcode刷题1117h2o生成

215 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

leetcode刷题1117h2o生成

前文

本文为leetcode多线程类型题目,题目序号为1117,主要考察对于多线程相关知识的应用。

题目信息

现在有两种线程,氧 oxygen 和氢 hydrogen,你的目标是组织这两种线程来产生水分子。 存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来。 氢和氧线程会被分别给予 releaseHydrogen 和 releaseOxygen 方法来允许它们突破屏障。 这些线程应该三三成组突破屏障并能立即组合产生一个水分子。 你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。

解题思路

该题目的解题思路根据题目信息来说,主要是对于线程顺序的控制。通过CyclicBarrier进行每一组元素的控制,保证每组元素均为两个氢元素一个氧元素。而与此同时,采用信号量关键字Semaphore。两种线程交替进行信号量元素的控制,保证两种元素的比例维持2:1,适配题目要求。以此方式交替控制即可得到目标的打印结果。

解题代码

class H2O {

    private Semaphore oxygenSp = new Semaphore(2);//o
    private Semaphore hydrogenSp = new Semaphore(2);//h
    private CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
    public H2O() {

    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {

        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        hydrogenSp.acquire(1);
        try {
            cyclicBarrier.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        releaseHydrogen.run();
        oxygenSp.release(1);
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {

        // releaseOxygen.run() outputs "O". Do not change or remove this line.
        oxygenSp.acquire(2);
        try {
            cyclicBarrier.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        releaseOxygen.run();
        cyclicBarrier.reset();
        hydrogenSp.release(2);
    }
}

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。