美文网首页
信号量:semaphore

信号量:semaphore

作者: topshi | 来源:发表于2019-05-06 15:19 被阅读0次

    允许多个线程同时访问:信号量semaphore

    信号量为多线程协作提供了更为强大的控制方法。无论是内部锁synchronized还是重入锁ReentranctLock,一次只允许一个线程访问资源,而信号量可以指定多个线程同时访问某一个资源。
    信号量的构造函数:

        public Semaphore(int permits) {
            this.sync = new Semaphore.NonfairSync(var1);
        }
    
        public Semaphore(int permits, boolean fair) {
            this.sync = (Semaphore.Sync)(var2 ? new Semaphore.FairSync(var1) : new Semaphore.NonfairSync(var1));
        }
    

    permiits参数指定信号量的准入数,也就是同时能申请多少个许可。当一个线程只允许申请一次时,相当于指定多少个线程可以访问某一个资源。fair参数指定是否公平。
    信号量主要逻辑方法:

    public void acquire() throws InterruptedException 
    public void acquireUninterruptibly() 
    public boolean tryAcquire() 
    public boolean tryAcquire(long time, TimeUnit unit) throws InterruptedException 
    public void release()
    
    • acquire()方法尝试获得一个准入许可,若无法获得,则线程等待,直到其他线程释放一个许可或当前线程中断。
    • acquireUninterruptibly()方法和acquire()类似,但是它不响应中断。
    • tryAcquire()方法尝试获得一个许可,若成功则返回true,失败则返回false,不等待。
    • tryAcquire(long time, TimeUnit unit)方法和tryAcquire()类似,但它会等待时间time
    • release()方法在线程访问资源结束后,释放一个许可。

    Semaphore示例

    package semaphore;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    /**
     * @Time : 2019/05/06 下午 02:47
     * @Author : xiuc_shi
     **/
    public class SemaphoreDemo implements Runnable {
        final Semaphore semaphore = new Semaphore(5);
        @Override
        public void run() {
            try {
                semaphore.acquire();
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getId() + " Done");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                semaphore.release();
            }
        }
        public static void main(String[] args) {
            ExecutorService es = Executors.newFixedThreadPool(20);
            final SemaphoreDemo demo = new SemaphoreDemo();
            for(int i = 0;i < 20;i++){
                es.execute(demo);
            }
            es.shutdown();
        }
    }
    

    信号量用完必须释放,和释放锁一样,否则可用的信号量会越来越少。

    应用场景

    Semaphore可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有10个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候,就可以使用Semaphore来做流量控制。(摘自《java并发编程的艺术》)

    相关文章

      网友评论

          本文标题:信号量:semaphore

          本文链接:https://www.haomeiwen.com/subject/tagroqtx.html