Semaphore
получает сразу все разрешения, иначе это не будет настоящий семафор .НО: версия Java также имеет внутреннюю очередь ожидания.И поведение этой очереди НЕ наилучшим образом соответствует свободным в настоящее время ресурсам , но более или менее разрешений на сбор, пока не будет разрешен запрос первого в очереди .Но перед тем, как поток входит в , в эту очередь выполняется проверка, если доступные разрешения позволяют потоку вообще не заходить в очередь.
Я изменил ваш код, чтобы показать поведение этой очереди:
import java.util.concurrent.*;
public class SemaphoreTest{
static Semaphore s = new Semaphore(0);
public void fun(final char c, final int r) throws Exception {
new Thread(new Runnable(){
public void run(){
try{
System.out.println("acquire "+r);
s.acquire(r);
System.out.println(c+"_"+r);
} catch(Exception e){ e.printStackTrace(); }
}
}).start();
Thread.sleep(500);
}
public static void main(String[]args) throws Exception{
SemaphoreTest f = new SemaphoreTest();
f.fun('B',2);
f.fun('F',6);
f.fun('A',1);
f.fun('C',3);
f.fun('D',4);
f.fun('E',5);
while(s.hasQueuedThreads()){
Thread.sleep(1000);
System.out.println("release "+1+", available "+(s.availablePermits()+1));
s.release(1);
}
}
}
В основном были сделаны следующие изменения:
- Начните с 0 разрешений - пусть кто-нибудь сначала войдет в очередь.
- "Определите" порядок очередейдавая каждому потоку 500 мс времени после
Thread.start
. - Каждый поток будет вызывать
acquire
, но не release
. - Основной поток будет медленно подавать семафор с одним разрешением за другим.
Это даст этот вывод определенно:
acquire 2
acquire 6
acquire 1
acquire 3
acquire 4
acquire 5
release 1, available 1
release 1, available 2
B_2
release 1, available 1
release 1, available 2
release 1, available 3
release 1, available 4
release 1, available 5
release 1, available 6
F_6
release 1, available 1
A_1
release 1, available 1
release 1, available 2
release 1, available 3
C_3
release 1, available 1
release 1, available 2
release 1, available 3
release 1, available 4
D_4
release 1, available 1
release 1, available 2
release 1, available 3
release 1, available 4
release 1, available 5
E_5
release 1, available 1
Что означает: каждый поток пробуждается, если
- он находится во главеочередь.
- накоплено достаточно разрешений.