码迷,mamicode.com
首页 > 编程语言 > 详细

多线程-java.util.concurrent-Semaphore

时间:2021-02-09 12:33:43      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:api   port   线程   编程   有一个   reduce   任务   获取数据   cti   

什么是Semaphore信号量:

  Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

正常的锁(synchronized锁或Lock锁)在任何时刻都只允许一个任务访问一项资源,而Semaphore允许n个任务访问这个资源。

API:

  Semaphore(int permits) 创建给定数量的许可和不公平设置的信号量
  Semaphore(int permits, boolean fair) 创建给定数量的许可和设置公平性的信号量
  void acquire() 从这个信号量获取许可证,阻塞直到一个有一个信号量可用或者线程被打断为止
  void acquire(int permits) 从这个信号量获取给定数量的许可证,阻塞直到一个有一个信号量可用或者线程被打断为止
  void acquireUninterruptibly() 从这个信号量获取许可证,阻塞直到一个信号量可用位置,不响应中断
  void tryAcquire() 从这个信号量获取一个许可证,只有在调用时一个信号量可用
  void tryAcquire(int permits)
  void tryAcquire(int permits, long timeout, TimeUnit timeUnit)
  void tryAcquire(long timeout, TimeUnit timeUnit)
  void release() 释放许可证,将其返回给信号量。

  int availablePermits() :返回此信号量中当前可用的许可证数
  int getQueueLength():返回正在等待获取许可证的线程数  
  boolean hasQueuedThreads() :是否有线程正在等待获取许可证
  void reducePermits(int reduction) :减少reduction个许可证。是个protected方法
  Collection getQueuedThreads() :返回所有等待获取许可证的线程集合。是个protected方法

应用场景:

  semaphore可以用作流量控制,特别是公共资源有限的应用场景,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型

任务,我们可以启动几十个线程并发的读取,但是如果读到内存后,还需要存储到数据库中,二数据库的连接数只有10个,这时我们必须控制只有10个线

程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候就可以用semaphore来做流量控制。

示例:   

package org.burning.sport.javase.thread.semaphore;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreTest {
    private static ExecutorService exec = Executors.newFixedThreadPool(30);
    private static ThreadPoolManager threadPool = ThreadPoolManager.getInstanceThreadPool();
    private static Semaphore semaphore = new Semaphore(10);

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {

            exec.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire(); //访问许可
                        System.out.println("执行任务中.....");
                        semaphore.release(); //访问完成,释放
                        System.out.println("--------" + semaphore.availablePermits());

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        exec.shutdown();
        threadPool.shutdown();
    }
}

 

参考:

  【1】《Think In Java》4th

  【2】《Java并发编程艺术》,方腾飞

  【3】《Java》高并发程序设计,葛一鸣

 

多线程-java.util.concurrent-Semaphore

标签:api   port   线程   编程   有一个   reduce   任务   获取数据   cti   

原文地址:https://www.cnblogs.com/happyflyingpig/p/10030028.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!