Семафор Java увеличивает количество разрешений, когда я выпускаю больше, чем число приобретений - PullRequest
0 голосов
/ 09 сентября 2018

Я изучаю Mutex и семафор в Java. Поэтому я подумал о том, чтобы испачкать руки.

Я понимаю, что мьютекс - это семафор с единственным разрешением из этой ссылки , и мьютекс имеет концепцию владения из этой ссылки .

Чтобы продемонстрировать право владения, я написал программу ниже и нашел вывод ниже. Когда я выпускаю больше, чем приобретаю, это фактически увеличивает количество разрешений.

Ниже приведена программа.

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 голосов
/ 09 сентября 2018

Пара вещей:

  • вы используете Semaphore, который может иметь любое количество разрешений, так что да, это ожидается. См. Javadoc :

Нет требования, чтобы поток, который выпускает разрешение, имел получил это разрешение, позвонив по номеру acquire(). Правильное использование Семафор устанавливается соглашением программирования в приложении.

  • вы не используете несколько потоков, поскольку вы всегда блокируете фьючерсы. Ваш код полностью последовательный.
  • когда люди говорят, что мьютекс - это семафор с одним разрешением, они говорят об абстрактных концепциях, а не о реализации Java. Примером мьютексов в Java может быть ReentrantLock или простой Object, используемый с блоком synchronized.
0 голосов
/ 09 сентября 2018

Да, это ожидаемое поведение, приведенное в документации :

[...] Выпускает разрешение, увеличивая количество доступных разрешений на единицу. [...] Нет требования, чтобы поток, который выпускает разрешение, получил это разрешение путем вызова 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
...