セマフォセマフォは、同時スレッドの数を制御するために使用されます。
ミューテックス相互排他ロックは、同時に 1 つのスレッドの実行のみを制御します。
2 つの間の最も重要な違いは、所有権の概念です。ミューテックスには所有権があります。ミューテックスは一度に 1 つのスレッドのみが保持できますが、セマフォには所有権がありません。どのスレッドもこのオブジェクトのメソッドを呼び出すことができます。
セマフォは3つのスレッドの同時実行を制御します
final int clientCount = 3;
final int totalRequestCount = 10;
Semaphore semaphore = new Semaphore(clientCount);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalRequestCount; i++) {
executorService.execute(()->{
try {
semaphore.acquire();
System.out.println("thread start do something :" + Thread.currentThread() + " :" + semaphore.availablePermits() + " ");
Thread.sleep(1000);
System.out.println("thread finish do something :" + Thread.currentThread() + " :" + semaphore.availablePermits() + " ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
});
}
executorService.shutdown();
印刷:
thread start do something :Thread[pool-1-thread-1,5,main] :0
thread start do something :Thread[pool-1-thread-3,5,main] :0
thread start do something :Thread[pool-1-thread-2,5,main] :0
thread finish do something :Thread[pool-1-thread-1,5,main] :0
thread finish do something :Thread[pool-1-thread-2,5,main] :0
thread finish do something :Thread[pool-1-thread-3,5,main] :1
thread start do something :Thread[pool-1-thread-5,5,main] :1
thread start do something :Thread[pool-1-thread-4,5,main] :1
thread start do something :Thread[pool-1-thread-7,5,main] :0
...
Mutex は 1 つのスレッドを制御して同時実行します。
final int totalRequestCount = 10;
final ReentrantLock mutex = new ReentrantLock();
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalRequestCount; i++) {
executorService.execute(()->{
try {
mutex.lock();
System.out.println("thread start do something :" + Thread.currentThread());
Thread.sleep(1000);
System.out.println("thread finish do something :" + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.unlock();
}
});
}
executorService.shutdown();
印刷:
thread start do something :Thread[pool-1-thread-1,5,main]
thread finish do something :Thread[pool-1-thread-1,5,main]
thread start do something :Thread[pool-1-thread-2,5,main]
thread finish do something :Thread[pool-1-thread-2,5,main]
thread start do something :Thread[pool-1-thread-3,5,main]
thread finish do something :Thread[pool-1-thread-3,5,main]
thread start do something :Thread[pool-1-thread-4,5,main]
thread finish do something :Thread[pool-1-thread-4,5,main]
thread start do something :Thread[pool-1-thread-5,5,main]
thread finish do something :Thread[pool-1-thread-5,5,main]
...