【问题标题】:Java semaphore increases the number of permits when I do release more than number of the acquires当我发布的数量超过获取数量时,Java 信号量会增加许可数量
【发布时间】:2019-02-14 07:26:17
【问题描述】:

我正在学习 Java 中的 Mutex 和 Semaphore。所以我想弄脏我的手。

我知道 mutex 是来自此 link 的具有单一许可的信号量,并且 mutex 具有来自此 link 的所有权概念。

为了证明所有权,我编写了下面的程序并在下面找到了输出。 当我确实释放多于获取时,它实际上增加了许可的数量。

下面是程序。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;

public class MutexOwnerShipDemo {
    public static void main(String[] args) {
        Semaphore mutex = new Semaphore(1);
        final ExecutorService es = Executors.newSingleThreadExecutor();
        try {
            // acquire mutex lock permit in main thread
            mutex.acquire();

            // release the lock in different thread
            Future mutexWait = es.submit(() -> mutex.release());
            mutexWait.get();
            System.out.println("mutexWait.isDone() " + mutexWait.isDone() );
            System.out.println("successfully released permits for mutex \n " +
                "available permits are " + mutex.availablePermits());

            // release the lock in main thread
            mutex.release();
            System.out.println( "available permits are " + mutex.availablePermits());

            // release lock in main thread once again
            mutex.release();
            System.out.println( "available permits are " + mutex.availablePermits());
        } catch (Exception e) {

        }
        Runtime.getRuntime().addShutdownHook(new Thread(() -> es.shutdownNow()));
        System.out.println(es.isShutdown());
    }
}

输出是 -

mutexWait.isDone() true
successfully released permits for mutex 
available permits are 1
available permits are 2
available permits are 3
false

这是预期的行为。如果是这样,它是如何工作的

我的java安装细节-

$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

【问题讨论】:

  • 如果您想要Lock 行为,请使用LockSemaphore 不是 Lock

标签: java java-8 mutex semaphore


【解决方案1】:

是的,这是the documentation 中引用的预期行为:

[...] 释放许可证,将可用许可证的数量增加一。 [...] 不要求释放许可的线程必须通过调用acquire()获得该许可

您可以释放任意数量的许可证:

Semaphore semaphore = new Semaphore(0);
semaphore.release(10); // it's fine
System.out.println(semaphore.availablePermits()); // 10

但是,您无法获得随机数量的许可(准确地说,是超过当前可用许可数量的数字):

Semaphore semaphore = new Semaphore(0);
semaphore.acquire(10); // you are blocked here

Semaphore semaphore = new Semaphore(0);
System.out.println(semaphore.tryAcquire(10)); // false

【讨论】:

    【解决方案2】:

    有几点:

    • 您正在使用Semaphore,它可以有任意数量的许可,所以是的,这是意料之中的。见Javadoc

    没有要求释放许可的线程必须具有 通过致电acquire() 获得该许可。 a的正确使用 信号量是由应用程序中的编程约定建立的。

    • 您没有使用多个线程,因为您总是在未来阻塞。您的代码是完全顺序的。
    • 当人们说互斥锁是具有单一许可的信号量时,他们指的是抽象概念,而不是 Java 实现。 Java 中的互斥锁示例是 ReentrantLock,或与 synchronized 块一起使用的简单 Object

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 2012-01-05
      • 2023-03-11
      相关资源
      最近更新 更多