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

Posted 程序员牧码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
        
    

以上是关于LeetCode(多线程)- 1117. H2O 生成的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1117. Building H2O

LeetCode——H2O生成(多线程)

LeetCode 多线程练习2(1116. 打印零与奇偶数 / H2O 生成)

LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口

LeetCode——多线程问题汇总

1117. H2O 生成