Semaphore调试

一Semaphore

通过许可证管理多个线程的执行,有许可证的线程可以执行,没有许可证的线程会等待。



 

二Semaphore方法说明

  1. Semaphore(permits):初始化许可证数量的构造函数
  2. Semaphore(permits,fair):初始化许可证数量和是否公平模式的构造函数
  3. isFair():是否公平模式FIFO
  4. availablePermits():获取当前可用的许可证数量
  5. acquire():
    1. 当前线程尝试去获取1个许可证。此过程是阻塞的,它会一直等待许可证,直到发生以下事:
      1. 当前线程获取了1个可用的许可证,则会停止等待,继续执行。
      2. 当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。
  6. acquire(permits):
    1. 当前线程尝试去获取permits个许可证。此过程是阻塞的,它会一直等待许可证,直到发生以下事
      1. 当前线程获取了n个可用的许可证,则会停止等待,继续执行。
      2. 当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。
  7. acquierUninterruptibly():
    1. 当前线程尝试去阻塞的获取1个许可证(不可中断的)。此过程是阻塞的,它会一直等待许可证,直到发生以下事
      1. 当前线程获取了1个可用的许可证,则会停止等待,继续执行。
  8. acquireUninterruptibly(permits):
    1. 当前线程尝试去阻塞的获取permits个许可证。此过程是阻塞的,它会一直等待许可证,直到发生以下事
      1. 当前线程获取了n个可用的许可证,则会停止等待,继续执行。
  9. tryAcquire():当前线程尝试去获取1个许可证。
    1. 此过程是非阻塞的,它只是在方法调用时进行一次尝试。
    2. 如果当前线程获取了1个可用的许可证,则会停止等待,继续执行,并返回true。
    3. 如果当前线程没有获得这个许可证,也会停止等待,继续执行,并返回false。
  10. tryAcquire(permits):当前线程尝试去获取permits个许可证。
    1. 此过程是非阻塞的,它只是在方法调用时进行一次尝试。
    2. 如果当前线程获取了permits个可用的许可证,则会停止等待,继续执行,并返回true。
    3. 如果当前线程没有获得permits个许可证,也会停止等待,继续执行,并返回false。
  11. tryAcquire(timeout,TimeUnit):当前线程在限定时间内,阻塞的尝试去获取1个许可证
    1. 此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:
    2. 当前线程获取了可用的许可证,则会停止等待,继续执行,并返回true。
    3. 当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
    4. 当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
  12. tryAcquire(permits,timeout,TimeUnit):当前线程在限定时间内,阻塞的尝试去获取permits个许可证。
    1. 此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:
    2.  当前线程获取了可用的permits个许可证,则会停止等待,继续执行,并返回true。
    3.  当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
    4. 当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
  13. release():当前线程释放1个可用的许可证。
  14. release(permits):当前线程释放permits个可用的许可证。
  15. drainPermits():当前线程获得剩余的所有可用许可证。
  16. hasQueuedThreads():判断当前Semaphore对象上是否存在正在等待许可证的线程。
  17. getQueueLength():获取当前Semaphore对象上是正在等待许可证的线程数量。

 

三案例

public class SemaphoreTest {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        final Semaphore sp = new Semaphore(3);
        for (int i = 0; i < 4; i++) {
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        sp.acquire();//获取许可证

                        System.out.println("执行:线程" + Thread.currentThread().getName());
                        System.out.println("当前许可证数量:" + sp.availablePermits());

                        System.out.println("每个线程走到这里都等待5秒");
                        Thread.sleep(5000);
                        System.out.println("正在等待许可证的线程数量:" + sp.getQueueLength());
                        sp.release();//释放许可证
                        System.out.println("当前许可证数量:" + sp.availablePermits());
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }

    }

}

四结果分析

执行:线程pool-1-thread-2
当前许可证数量:2
每个线程走到这里都等待5秒
执行:线程pool-1-thread-1
当前许可证数量:1
每个线程走到这里都等待5秒
执行:线程pool-1-thread-4
当前许可证数量:0
每个线程走到这里都等待5秒

------------解释

代码都到这里,说明有3个线程(2,1,4)拿到许可证并执行了,有一个线程还没有拿到许可证,因为总的许可证只有3个。

------------解释

 

正在等待许可证的线程数量:1
当前许可证数量:1

------------解释

当前许可证数量1,说明已经有一个线程释放了许可证,那么等待许可证的那个线程可以执行了

------------解释

执行:线程pool-1-thread-3
当前许可证数量:0
每个线程走到这里都等待5秒

 


正在等待许可证的线程数量:0
当前许可证数量:1
正在等待许可证的线程数量:0
当前许可证数量:2
正在等待许可证的线程数量:0
当前许可证数量:3

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java基础)