当我确实发布的数量超过获取数量时,Java信号量会增加许可数量

时间:2018-09-09 19:31:39

标签: java java-8 mutex semaphore

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

我了解互斥体是此link的单许可信号灯,互斥体具有此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)

2 个答案:

答案 0 :(得分:6)

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

  

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

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

for (i, j in c(1,2,3), c("a","b","c")){
print(i)
print(j)
}

您不能获得随机数量的许可证(准确地说,这个数量超出了当前可用的许可证数量),

1
a
2
b
3
c

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

答案 1 :(得分:3)

几件事:

  • 您正在使用Semaphore,它可以具有任意数量的许可,因此可以预期。参见Javadoc
  

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

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