0
点赞
收藏
分享

微信扫一扫

H2O的生成

小美人鱼失去的腿 2022-01-09 阅读 64

题目简介

解答

方法一

synchronized

class H2O {

    private int hydrogen;
    private int oxygen;
    
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        synchronized (this){
            while (hydrogen == 2){//循环判断条件变量
                wait();
            }
            hydrogen++;
            releaseHydrogen.run();
            if (hydrogen == 2 && oxygen == 1){
                hydrogen = 0;
                oxygen = 0;
                notifyAll();
            }
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        // releaseOxygen.run() outputs "O". Do not change or remove this line.
        synchronized (this){
            while (oxygen == 1){
                wait();
            }
            oxygen++;
            releaseOxygen.run();
            if (hydrogen == 2 && oxygen == 1){
                hydrogen = 0;
                oxygen = 0;
                notifyAll();
            }
        }
    }
}
解答成功:
		执行耗时:13 ms,击败了99.23%Java用户
		内存消耗:39.9 MB,击败了67.51%Java用户
		

方法二

Lock + Condition

class H2O {
    private volatile int hydrogen;
    private volatile int oxygen;
    private final Lock lock = new ReentrantLock(false);
    private Condition condition = lock.newCondition();

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
		lock.lock();
        try {
            while (hydrogen  == 2){
                condition.await();
            }
            releaseHydrogen.run();
            hydrogen++;
            if (hydrogen == 2 && oxygen == 1){
                hydrogen = 0;
                oxygen = 0;
                condition.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        lock.lock();
        try {
            while (oxygen == 1){
                condition.await();
            }
            releaseOxygen.run();
            oxygen++;
            if (hydrogen == 2 && oxygen == 1){
                hydrogen = 0;
                oxygen = 0;
                condition.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }
}
解答成功:
		执行耗时:14 ms,击败了90.85%Java用户
		内存消耗:40.1 MB,击败了37.59%Java用户

方法三

信号量

Semaphore

class H2O {
    private Semaphore h = new Semaphore(2); //两个H
    private Semaphore o = new Semaphore(0);//一个O
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        h.acquire();//获取一个氢元素,没有就阻塞
        releaseHydrogen.run();
        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        if(h.availablePermits() == 0) {//实时判断当前还有几个H元素可以被提供
            o.release(); //添加一个氧元素
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        o.acquire();//获取一个氢元素,没有就阻塞
        releaseOxygen.run();
        if (h.availablePermits() == 0){//实时判断当前还有几个H元素可以被提供
            h.release(2);//添加两个氢元素
        }
    }
}
解答成功:
		执行耗时:14 ms,击败了90.85%Java用户
		内存消耗:40 MB,击败了56.89%Java用户

方法四

Semaphore + CyclicBarrier

class H2O {
    private Semaphore h = new Semaphore(2);
    private Semaphore o = new Semaphore(1);
    //直到三个线程都到了await点,才执行run方法,也就是刚好凑齐一个水分子H20
    private CyclicBarrier  cyclicBarrier = new CyclicBarrier(3,()->{
        h.release(2);
        o.release();
    });
    public H2O() {
    }
    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        h.acquire();
        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        releaseHydrogen.run();
        try {
            cyclicBarrier.await();
        } catch (Exception e) {}
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        o.acquire();
        // releaseOxygen.run() outputs "O". Do not change or remove this line.
        releaseOxygen.run();
        try {
            cyclicBarrier.await();
        } catch (Exception e) {}
    }
}
解答成功:
		执行耗时:14 ms,击败了90.53%Java用户
		内存消耗:42 MB,击败了8.92%Java用户
举报

相关推荐

0 条评论