semaphore 使用详解,Java Semaphore

  semaphore 使用详解,Java Semaphore

  00-1010简介、简介、实现原理、方法介绍、案例分析、适用场景

  

目录

semaphore中文意思是信号量,主要作用是控制一个资源同时被访问的线程数量。

 

  为了控制对资源块的并发访问,可以使用Semaphore对象中的acquire()方法来获取访问令牌。如果信号量对象的访问令牌已经发出,当前获取令牌的线程将被阻塞。当其他线程释放()释放令牌时,当前线程将有机会获取令牌并拥有访问权限。

  

简介

信号量实际上是一个共享锁,因为它允许多个线程同时获取共享资源。创建Semaphore对象时,必须设置可用令牌许可的初始数量,该数量用于控制并发期间同时获取资源许可的线程数量。Semaphore类继承了同步队列AbstractQueuedSynchronizer。在这个类中,有一个属性state用于标记当前并发队列的数量,即获得令牌的线程的数量。然后,当获取()时,它将尝试获取共享锁。成功获取锁后,状态值将加1。如果状态值已经达到允许,就意味着令牌已经被调度,当前线程将进入阻塞状态。当其他线程释放()时,状态值会减1,然后从队列中获取头线程唤醒,获取资源访问的令牌。

 

  如下图所示,如果你仔细看源代码,你会发现信号量实际上是通过重写AbstractQueuedSynchronizer中的tryAcquireShared()和tryReleaseShared()方法实现的。

  

简述实现原理

信号量重载两个构造函数。一种是信号量(int permits)直接指定令牌数,默认是不公平锁;二、Semaphore (Int Permits,Boolean fair),fair参数表示线程抢占令牌的公平性,true为公平锁,否则为不公平锁。默认情况下,Acquire()没有获取令牌的参数,acquire(int permissions)使用指定的令牌数获取令牌数。如果没有足够的令牌,当前线程将被阻塞。TryAcquire()没有参数表明它试图获取令牌。这个方法是非阻塞的,所以如果令牌数不够,获取失败,返回false,否则返回true;同时,try acquire(int permissions)方法被重载,以指定要获取的令牌数。try acquire(int permissions,long timeout,time unit unit)尝试在有效时间内获取指定数量的令牌,如果超时后仍未获取令牌,则返回false,否则返回true。Release同上,支持无参与指定发布令牌数量的方法。drain permissions()获取剩余的可用令牌。HasQueuedThread()用于确定当前Semaphare实例中是否有线程等待获取令牌。

 

  00-1010分析以下短代码。首先创建一个信号量为5的信号量对象,然后创建一个线程池(实际开发中为了这里演示方便不推荐使用这个线程池),使用for循环并行运行100个线程。当一个线程运行时,它优先获得一个令牌,我们在线程的业务代码中睡眠1秒。为了展示等待令牌的效果,我们将执行延迟了1秒。

  @Slf4jpublic类Semaphore demo { public static void main(String[]args){ Semaphore Semaphore=new Semaphore(5);ExecutorService ExecutorService=executors . newcachedthreadpool();for(int I=0;i 100I){ executorservice . execute(()-{ try { semaphore . acquire();Log.info(令牌获取成功);时间单位。seconds . sleep;} catch(interrupted exception e){ e . printstacktrace();} finally {log.info(释放令牌);semaphore.release()。} });} executorservice . shut down();}}运行结果从下图所示的运行结果可以看出。100个线程的并发不是一次全部执行,而是等待前一个线程释放令牌的线程可以获得令牌运行业务代码。

  

方法介绍

信号量主要用于限制多线程环境下对某些共享资源的访问,防止多个线程并发访问同一个资源,可能导致大部分线程在获取资源时需要锁。如果是获取数据库中的数据,可以缓解数据库的压力。

 

  另一种情况是多线程运行的流量限制。一般我们可能会通过线程池一步控制线程数,但有些业务为了减轻CPU的负担,还是会限制同时运行的线程数。

  关于如何在Java中使用信号量的文章到此结束。更多关于信号量使用的相关内容,请搜索Popular IT以前的文章或者继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: