信号灯类Semaphore:
一个计数信号量,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。
单个信号量可以实现互斥锁的功能并且可以是由一个线程获得了锁,再由另一个线程释放,
此时只允许一个线程进去访问某些资源。该类对象可以维护当前访问自身的线程的个数,
并提供了同步的机制,它控制同时访问资源的线程个数,例如实现一个同时访问文件的并发访问。
打个不恰当的例子:之前学的线程同步与互斥相当于我们去洗手,但是只有一个水龙头,很多人
都在等,当一个人获得洗手的资格,其他人就不能去洗,只有等到这个人洗完了,释放了水龙头
其他等的人才能洗。而信号灯就相当于,这里有3个水龙头,但是依然是很多人在排队洗手,只有
当在洗手的三个人中有人洗完了,释放了水龙头,其余等的人才能去洗,这样一次就是有三个人同时洗手。
示例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /* * 创建一个缓存线程池,当向线程池丢入10个任务的时候,缓存线程池会生成10个线程去执行这10个任务, * 然后创建一个信号量对象,一次只允许3个线程同时访问资源,只有当三个线程中的某一个释放了信号灯, * 其他7个等待的线程才有机会执行,当然要看谁拿到该信号灯。 */ public class SempaphoreTest { public static void main(String[] args) { //创建一个缓存线程池 ExecutorService pools = Executors.newCachedThreadPool(); //创建具有给定的许可数和给定的公平设置的 Semaphore final Semaphore sp = new Semaphore(3,true); //向线程池中扔10个任务 for(int i=0;i<10;i++) { Runnable runnable = new Runnable() { @Override public void run() { //上锁 try { sp.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程" + Thread.currentThread().getName() + "进入,当前有" + (3-sp.availablePermits()) + "个并发"); try { Thread.sleep((long)(Math.random()*10000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程" + Thread.currentThread().getName() + "即将离开"); sp.release();//释放信号灯 System.out.println("线程" + Thread.currentThread().getName() + "已经离开,当前有" + (3-sp.availablePermits()) + "个并发"); } }; pools.execute(runnable); } } }
Java线程之信号灯的使用
最新推荐文章于 2023-04-15 16:00:59 发布