Semaphore - java多线程100例-7

it2026-06-19  8

Semaphore 的作用是限流,例如食堂只有5个窗口,放学后好多同学都来排队打饭,这个时候就可以用到这个信号量工具。

例如,自定义池子里面有里面有5个许可证,每个人想要打饭的人都来竞争池子里面的许可证,只有拿到的人才可以取打饭。

acquire()  获取1个许可 acquire(2) 获取2个许可 如果许可没有了或不够了就一直阻塞等待其他线程release,直到拿到许可为止。

@Test public void testAcquire() throws InterruptedException { Semaphore semaphore = new Semaphore(5); semaphore.acquire(2); System.out.println("acquired 2" ) ; for (int i = 0; i < 4; i++) { semaphore.acquire(); System.out.println("acquired" + 1); } }

执行结果:

 

tryAcquire()  不阻塞等待获取一个许可,如果获取到返回true如果没有直接返回false tryAcquire(4) 不阻塞等待4个许可,如果获取到返回true如果没有直接返回false tryAcquire(2, TimeUnit.SECONDS) 等待2秒获取许可,如果获取到返回true如果没有直接返回false tryAcquire(2,3,TimeUnit.SECONDS) 等待3秒获取2个许可,如果获取到返回true如果没有直接返回false

@Test public void testTryAcquire() throws InterruptedException { Semaphore semaphore = new Semaphore(3); System.out.println(semaphore.tryAcquire(4)+" | "+ Calendar.getInstance().get(Calendar.SECOND)); for (int i = 0; i < 6; i++) { System.out.println(semaphore.tryAcquire() +" | "+ Calendar.getInstance().get(Calendar.SECOND)); } System.out.println(semaphore.tryAcquire(2, TimeUnit.SECONDS)+" | "+ Calendar.getInstance().get(Calendar.SECOND)); System.out.println(semaphore.tryAcquire(2,3,TimeUnit.SECONDS)+" | "+ Calendar.getInstance().get(Calendar.SECOND)); }

执行结果:

 

 

availablePermits() 查看还剩几个许可 hasQueuedThreads() 查看是否有线程在等待那许可 getQueueLength()   查看几个线程在等待那许可

@Test public void testOtherMethod() throws InterruptedException { // new 5 个许可 Semaphore semaphore = new Semaphore(5); // 取完所有许可 semaphore.drainPermits(); //查看还说几个许可 System.out.println(semaphore.availablePermits() + " availablePermits "); //查看是否有线程在等待那许可 System.out.println(semaphore.hasQueuedThreads() + " hasQueuedThreads "); //new 2个线程取许可,这时候没有许可存在所以等待 new Thread(()->{ try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(()->{ try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); Thread.sleep(1000); //查看是否有线程等待 System.out.println(semaphore.hasQueuedThreads() + " hasQueuedThreads "); //查看等待线程的个数 System.out.println(semaphore.getQueueLength() + " getQueueLength "); }

执行结果:

最新回复(0)