JDK的并发包中提供了几个非常有用的工具类,这些工具类给我们在业务开发过程中提供了一种并发流程控制的手段。设置并发数
Semaphore也叫信号量,在JDK1.5被引入,可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。
Semaphore内部维护了一组虚拟的许可,许可的数量可以通过构造函数的参数指定。访问特定资源前,必须使用acquire方法获得许可,如果许可数量为0,该线程则一直阻塞,直到有可用许可。访问资源后,使用release释放许可。Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。
应用场景:
Semaphore可以用来做流量分流,特别是对公共资源有限的场景,比如数据库连接。假设有这个的需求,读取几万个文件的数据到数据库中,由于文件读取是IO密集型任务,可以启动几十个线程并发读取,但是数据库连接数只有10个,这时就必须控制最多只有10个线程能够拿到数据库连接进行操作。这个时候,就可以使用Semaphore做流量控制。
public class SemaphoreTest {
private static final int COUNT = 40;
private static Executor executor = Executors.newFixedThreadPool(COUNT);
private static Semaphore semaphore = new Semaphore(10);
public static void main(String[] args) {
for (int i=0; i< COUNT; i++) {
executor.execute(new ThreadTest.Task()); }
} static class Task implements Runnable {
@Override
public void run() { try {
//读取文件操作
semaphore.acquire();
// 存数据过程
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace(); } finally { } } } }
当有多个线程时但是访问的某个资源(数据库)却是比较少的,所以为了节约资源可以引用Semaphore做为资源的一个调度。
里面的方法:
Semaphore(int m),参数代表信号量的总数(即允许的通过量)
Acquire()方法在没有许可的情况下,要获取许可的线程会阻塞,而tryAcquire()方法在没有许可的情况下会立即返回 false
Release()释放一个信号
drainPermits(),这个方法返回即可所有的许可数目,并将许可置0;后面不允许修改 availablePermits() 返回所有可用的许可数
isFair()该Semaphore是否是公平锁机制
如果要增加减少总许可数可以new Semaphore(int m)来创建