Semaphore vs Mutex

Semaphore semaphore, used to control the number of concurrent threads
Mutex mutex, control only one thread execution at the same time

The most important difference between the two is the concept of ownership. Mutex has ownership. It is a mutex that can only be held by one thread at a time, but Semaphore has no ownership. Any thread can call the method of this object.

Semaphore controls 3 threads to execute concurrently

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();

Print:

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 controls 1 thread to execute concurrently

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();

Print:

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]
...

Guess you like

Origin blog.csdn.net/mryang125/article/details/125557386