4

查看 1Z0-804 考试的一些文献,我找到了这个示例问题:

考虑以下程序:

class ATMRoom {
    public static void main(String []args) {
        Semaphore machines = new Semaphore(2); //#1
        new Person(machines, "Mickey");
        new Person(machines, "Donald");
        new Person(machines, "Tom");
        new Person(machines, "Jerry");
        new Person(machines, "Casper");
    }
}

class Person extends Thread {
    private Semaphore machines;
    public Person(Semaphore machines, String name) {
        this.machines = machines;
        this.setName(name);
        this.start();
    }
    public void run() {
        try {
            System.out.println(getName()
                + " waiting to access an ATM machine");
                machines.acquire();
            System.out.println(getName()
                + " is accessing an ATM machine");
            Thread.sleep(1000);
            System.out.println(getName()
                + " is done using the ATM machine");
            machines.release();
        } catch(InterruptedException ie) {
            System.err.println(ie);
        }
    }
}

如果将语句#1 替换为以下语句,哪一个选项是正确的? Semaphore machines = new Semaphore(2, true);

省略答案

正确答案的解释引起了我的注意:

第二个参数说明信号量对象的公平策略。但是,信号量对象有两个许可;所以你无法预测等待的人将获得使用 ATM 的权限的顺序。

我想说的是,不能仅仅因为线程的不确定性而预测顺序,而不是因为信号量中的许可数量,并且公平参数保证等待线程以它们获得的相同顺序被唤醒semaphore,但仍无法确定获取顺序。我的解释正确吗?

4

2 回答 2

1

据我了解,是的,您的想法是正确的,因为公平信号量使用 FairSync,并且它的获取机制不依赖于可用许可的数量,而只依赖于线程队列中的第一个线程:

        protected int tryAcquireShared(int acquires) {
        for (;;) {
            if (getFirstQueuedThread() != Thread.currentThread() &&
                hasQueuedThreads())
                return -1;
         ....
于 2013-05-30T13:26:59.130 回答
0

我想说,因为他们都start在他们的构造函数中调用,你只能保证线程的创建顺序和它们的启动顺序,你不能说他们的run方法被调用的顺序。

所以 - 基本上 - 你是对的,信号量的数量根本不影响顺序。

于 2013-05-30T13:15:26.527 回答