-1

这个问题来自 LeetCode。https://leetcode.com/problems/building-h2o/

对于不同的测试用例,我提出的以下代码大约有五分之一失败。其中一个测试用例是“HHOHHOOOOHHHHHH”。我没有重现这个确切测试用例的代码,因为它对用户隐藏,可以在网站上输入以下代码和测试用例进行重现。

public class H2O {
    final CyclicBarrier barrier = new CyclicBarrier(3);
    int h;
    int o;
    final Semaphore hydroWaiting = new Semaphore(0);
    final Semaphore oxWaiting = new Semaphore(0);
    final Lock lock = new ReentrantLock();

    public H2O() {

    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        lock.lock();
        h++;
        boolean last = false;
        if (h >= 2 && o >= 1) {
            h -= 2;
            o -= 1;
            oxWaiting.release(1);
            hydroWaiting.release(1);
            last = true;
        } else {
            lock.unlock();
            hydroWaiting.acquire();
        }
        try {
            System.out.println("Hydrogen Thread " + Thread.currentThread().getName() + " awaiting barrier");
            barrier.await();
            releaseHydrogen.run();
            System.out.println("Hydrogen Thread " + Thread.currentThread().getName() + " released");
        } catch (Exception e) {
            System.out.println("Barrier Broken");

        } finally {
            if (last) {
                lock.unlock();
            }
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        lock.lock();
        o++;
        boolean last = false;
        if (h >= 2 && o >= 1) {
            h -= 2;
            o -= 1;
            hydroWaiting.release(2);
            last = true;
        } else {
            lock.unlock();
            oxWaiting.acquire();
        }
        System.out.println("Oxygen Thread " + Thread.currentThread().getName() + " awaiting barrier");
        try {
            barrier.await();
            releaseOxygen.run();
            System.out.println("Oxygen Thread " + Thread.currentThread().getName() + " released");
        } catch (Exception e) {
            System.out.println("Barrier Broken");

        } finally {
            if (last) {
                lock.unlock();
            }
        }

    }

}

我花了很多时间调试,也尝试在我的本地重现,但没能做到。失败的运行具有我添加的打印语句的以下输出:

Output: "OOH HHH OHH OHH OHH" (spread out for readability)

Hydrogen Thread Thread-0 awaiting barrier
Hydrogen Thread Thread-1 awaiting barrier
Oxygen Thread Thread-2 awaiting barrier
Oxygen Thread Thread-2 released
Hydrogen Thread Thread-3 awaiting barrier
Hydrogen Thread Thread-4 awaiting barrier
Oxygen Thread Thread-5 awaiting barrier
Oxygen Thread Thread-5 released
Hydrogen Thread Thread-0 released
Hydrogen Thread Thread-1 released
Hydrogen Thread Thread-3 released
Hydrogen Thread Thread-4 released

如您所见,CyclicBarrier 的行为与输出的预期不同,即没有立即释放屏障中的所有线程。但这仅发生在 Leetcode 编译器中。有人可以指出代码中是否存在错误或者是 Leetcode 的问题吗?

4

0 回答 0