LeetCode(多线程)- 1117. H2O 生成

简介: LeetCode(多线程)- 1117. H2O 生成

题目链接:点击打开链接

题目大意:注意每一题的外部调用多线程,如果没特殊说明,想成每一个字符都是一个线程,只是装配的类是同一个,所以我们写的属性是能被共享有效的。

解题思路:略。

相关企业



  • 领英(LinkedIn)
  • 字节跳动
  • 亚马逊(Amazon)
  • 腾讯(Tencent)
  • 高盛集团(Goldman Sachs)
  • 英伟达(NVIDIA)
  • 谷歌(Google)
  • 微软(Microsoft)
  • Facebook
  • 阿里巴巴

AC 代码


// 方法1:Semaphore
class H2O {
    private Semaphore hSema = new Semaphore(2);
    private Semaphore oSema = new Semaphore(0);
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        hSema.acquire();
        releaseHydrogen.run();
        oSema.release();
    }
    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        oSema.acquire(2);
        releaseOxygen.run();
        hSema.release(2);
    }
}
// 方法2:Semaphore+CyclicBarrier
class H2O {
    private Semaphore hSema = new Semaphore(2);
    private Semaphore oSema = new Semaphore(1);
    private CyclicBarrier cb = new CyclicBarrier(3);
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        hSema.acquire();
        try {
            cb.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        releaseHydrogen.run();
        hSema.release();
    }
    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        oSema.acquire();
        try {
            cb.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        releaseOxygen.run();
        oSema.release();
    }
}
// 方法3:ReentrantLock+Condition
class H2O {
    private int oCnt = 0;
    private int hCnt = 0;
    private ReentrantLock lock = new ReentrantLock();
    private Condition con = lock.newCondition();
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        lock.lock();
        try {
            while (hCnt == 2) {
                con.await();
            }
            hCnt++;
            if (hCnt == 2 && oCnt == 1) {
                hCnt = 0;
                oCnt = 0;
            }
            releaseHydrogen.run();
            con.signalAll();
        } finally {
            lock.unlock();
        }
    }
    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        lock.lock();
        try {
            while (oCnt == 1) {
                con.await();
            }
            oCnt++;
            if (hCnt == 2 && oCnt == 1) {
                hCnt = 0;
                oCnt = 0;
            }
            releaseOxygen.run();
            con.signalAll();
        } finally {
            lock.unlock();
        }
    }
}
// 方法4:synchronized
class H2O {
    private int state = 0;
    private Object obj = new Object();
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        synchronized (obj) {
            while (state == 2) {
                obj.wait();
            }
            state++;
            releaseHydrogen.run();
            obj.notifyAll();
        }
    }
    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        synchronized (obj) {
            while (state != 2) {
                obj.wait();
            }
            state = 0;
            releaseOxygen.run();
            obj.notifyAll();
        }
    }
}
// 方法5:BlockingQueue
class H2O {
    private AtomicInteger cnt = new AtomicInteger();
    private BlockingQueue<Integer> hQ = new LinkedBlockingDeque<>(2);
    private BlockingQueue<Integer> oQ = new LinkedBlockingDeque<>(1);
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        hQ.put(1);
        releaseHydrogen.run();
        common();
    }
    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        oQ.put(1);
        releaseOxygen.run();
        common();
    }
    private void common() {
        cnt.incrementAndGet();
        if (cnt.intValue() == 3) {
            cnt.set(0);
            hQ.clear();
            oQ.clear();
        }
    }
}
目录
相关文章
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
7月前
Leetcode之多线程编程题
现有函数 printNumber 可以用一个整数参数调用,并输出该整数到控制台。 例如,调用 printNumber(7) 将会输出 7 到控制台。 给你类 ZeroEvenOdd 的一个实例,该类中有三个函数:zero、even 和 odd 。ZeroEvenOdd 的相同实例将会传递给三个不同线程:
117 1
|
数据采集
LeetCode(多线程)- 1242. 多线程网页爬虫
LeetCode(多线程)- 1242. 多线程网页爬虫
228 0
|
调度
leetcode.1114-按序打印-多线程案例
leetcode.1114-按序打印-多线程案例
112 0
leetcode线程题1116——打印零与奇偶数
leetcode线程题1116——打印零与奇偶数
106 0
leetcode线程题1117——H2O 生成(两个氢原子结合一个氧原子)
leetcode线程题1117——H2O 生成(两个氢原子结合一个氧原子)
100 0
|
调度
leetcode 线程题 1114. 按序打印
leetcode 线程题 1114. 按序打印
LeetCode(多线程)- 题集
LeetCode(多线程)- 题集
113 0
LeetCode(多线程)- 题集
LeetCode(多线程)- 1279. 红绿灯路口
LeetCode(多线程)- 1279. 红绿灯路口
340 0
LeetCode(多线程)- 1226. 哲学家进餐
LeetCode(多线程)- 1226. 哲学家进餐
112 0