leetcode-1117 悲观锁与乐观锁的实现

  看题目:

  第一种解法采用绝对悲观锁保证绝对的线程安全,思路很简单:不考虑线程协作写代码,然后找出单线程环境下存在控制依赖与数据依赖且涉及共享变量的部分,保证其原子性后确定互斥关系,决定那些操作是互斥的,则共用一把锁。

class H2O {

    int hNums=0;
    int oNums=0;

    public H2O() {
        
    }

    public final void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        while(true){
            while(hNums-oNums>=2){
                Thread.yield();
            }
            synchronized(this){
                if(hNums-oNums>=2){
                    continue;
                }
                // releaseHydrogen.run() outputs "H". Do not change or remove this line.
                releaseHydrogen.run();
                hNums++;
            }
            break;
        }
    }

    public final void oxygen(Runnable releaseOxygen) throws InterruptedException {
            while(true){
                while(hNums-oNums<2){
                    Thread.yield();
                }
                synchronized(this){
                    if(hNums-oNums<2){
                        continue;
                    }
                    // releaseOxygen.run() outputs "O". Do not change or remove this line.
                    releaseOxygen.run();
                    oNums++;
                }
                break;
            }
    }
}

  由于每个线程的任务耗时非常短,所以采用锁的方式大部分时间都消耗在了竞争锁和开锁上,这种情况下采用 CAS 结合繁忙等待效率会更高:

class H2O {

    private Semaphore h = new Semaphore(2);
    private Semaphore o = new Semaphore(0);

    public H2O() {
    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        h.acquire();
        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        releaseHydrogen.run();
        o.release();
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        o.acquire(2);
        // releaseOxygen.run() outputs "O". Do not change or remove this line.
        releaseOxygen.run();
        h.release(2);
    }
}

 

posted @ 2020-03-09 00:04  牛有肉  阅读(350)  评论(0编辑  收藏  举报