信号量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来实现。
 
 
  
信号量的应用场景,大多控制某一个并发资源的限制。例如抽出来的代码块 被多处引用,不容易控制其并发数,此时可以加入许可控制

posted @ 2021-02-16 20:22  以梦为码  阅读(159)  评论(0编辑  收藏  举报