Semaphore 信号灯,用来控制同时并发的线程数量
Mutex 互斥锁,控制同一时刻只能有一个线程执行
二者最重要的区别在于所有权这个概念,Mutex 具有所有权,它本身是一个互斥锁,在一个时刻只能被一个线程持有,但是Semaphore没有所有权,任何线程都可以调用此对象的方法。
Semaphore 控制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]
...