信号量Semaphore使用
semaphore:信号量,又称许可管理器,来控制线程的并发数量。
例如:
1、主线程设置许可数为2,标识最大允许并发线程数为2,前边的线程释放许可后,阻塞的线程才可以继续获取许可。信号量可以设置公平和非公平,当前设置为非公平
public static void main(String[] args) { Semaphore semaphore=new Semaphore(2,false); for(int i=0;i<10;i++){ new Thread(new Test01(semaphore)).start(); } }
2、子线程调用
public class Test01 implements Runnable{ private final Semaphore semaphore; public Test01(Semaphore semaphore) { this.semaphore=semaphore; } @Override public void run() { try { //获取许可,未获取阻塞 semaphore.acquire(); System.out.println("======我进来了"+Thread.currentThread().getName()); Thread.sleep(5000); //释放许可 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } //} } }
线程池与信号量的区别:
信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可的数量,每次线程执行操作时先通过acquire方法获得许可,执行完毕再通过release方法释放许可。如果无可用许可,那么acquire方法将一直阻塞,直到其它线程释放许可。
线程池用来控制实际工作的线程数量,通过线程复用的方式来减小内存开销。线程池可同时工作的线程数量是一定的,超过该数量的线程需进入线程队列等待,直到有可用的工作线程来执行任务。
使用Seamphore,你创建了多少线程,实际就会有多少线程进行执行,只是可同时执行的线程数量会受到限制。但使用线程池,你创建的线程只是作为任务提交给线程池执行,实际工作的线程由线程池创建,并且实际工作的线程数量由线程池自己管理。
简单来说,线程池实际工作的线程是work线程,不是你自己创建的,是由线程池创建的,并由线程池自动控制实际并发的work线程数量。而Seamphore相当于一个信号灯,作用是对线程做限流,Seamphore可以对你自己创建的的线程做限流(也可以对线程池的work线程做限流),Seamphore的限流必须通过手动acquire和release来实现。
信号量的应用场景,大多控制某一个并发资源的限制。例如抽出来的代码块 被多处引用,不容易控制其并发数,此时可以加入许可控制
Don’t hurry say have no choice, perhaps, next intersection will meet hope.