AQS—Semaphore

简单介绍

        Semaphore类可以控制并发访问的线程个数,可以很轻松地完成类似于操作系统里信号量的控制。Semaphore可以很容易地控制某个资源可被同时访问的个数,它提供了2个核心方法acquire()和release()方法,acquire()方法是获取一个许可,如果没有就在那等待,而release()方法则是在操作完成后释放一个许可出来。Semaphore维护了当前访问个数,提供同步机制,来控制同时访问个数。

使用场景

        Semaphore常用于仅能提供有限访问的资源,比如我们项目中使用到的数据库,数据库的连接数比如最大只有20,而我们上层应用的并发数可能远远大于20,如果同时对数据库进行操作,就可能会出现因为无法获取数据库连接而导致异常,这个时候我们就可以通过信号量Semaphore来做并发访问控制。

Semaphore使用举例一:

package com.yuxing.springbootdemo.juc;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SemaphoreExample {
	
	private static int threadCount = 20;
	
	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		final Semaphore semaphore = new Semaphore(3);
		for(int i = 0;i < threadCount;i++){
			final int threadNum = i;
			exec.execute(() -> {
				try {
					semaphore.acquire();//获取一个许可
					test(threadNum);
					semaphore.release();//释放一个许可
				} catch (InterruptedException e) {
					log.error("exception", e);
				}finally {
				}
			});
		}
		exec.shutdown();
	}
	
	private static void test(int threadNum) throws InterruptedException {
		log.info("{}", threadNum);
		Thread.sleep(1000);
	}
}

运行结果:

22:01:23.102 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 2
22:01:23.101 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 0
22:01:23.102 [pool-1-thread-2] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 1
22:01:24.106 [pool-1-thread-5] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 4
22:01:24.106 [pool-1-thread-4] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 3
22:01:24.106 [pool-1-thread-6] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 5
22:01:25.107 [pool-1-thread-8] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 7
22:01:25.107 [pool-1-thread-9] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 8
22:01:25.107 [pool-1-thread-7] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 6
22:01:26.107 [pool-1-thread-10] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 9
22:01:26.107 [pool-1-thread-11] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 10
22:01:26.107 [pool-1-thread-12] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 11
22:01:27.107 [pool-1-thread-13] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 12
22:01:27.107 [pool-1-thread-14] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 13
22:01:27.107 [pool-1-thread-16] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 15
22:01:28.108 [pool-1-thread-19] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 18
22:01:28.108 [pool-1-thread-18] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 17
22:01:28.108 [pool-1-thread-17] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 16
22:01:29.109 [pool-1-thread-15] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 14
22:01:29.110 [pool-1-thread-20] INFO com.yuxing.springbootdemo.juc.SemaphoreExample - 19

Semaphore使用举例二:

package com.yuxing.springbootdemo.juc;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SemaphoreExample2 {
	
	private static int threadCount = 20;
	
	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		final Semaphore semaphore = new Semaphore(3);
		for(int i = 0;i < threadCount;i++){
			final int threadNum = i;
			exec.execute(() -> {
				try {
					if(semaphore.tryAcquire()) {//尝试获取一个许可
						test(threadNum);
						semaphore.release();//释放一个许可
					}
				} catch (InterruptedException e) {
					log.error("exception", e);
				}finally {
				}
			});
		}
		exec.shutdown();
	}
	
	private static void test(int threadNum) throws InterruptedException {
		log.info("{}", threadNum);
		Thread.sleep(1000);
	}
}

运行结果:

22:09:29.373 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.SemaphoreExample2 - 0
22:09:29.373 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.SemaphoreExample2 - 2
22:09:29.373 [pool-1-thread-2] INFO com.yuxing.springbootdemo.juc.SemaphoreExample2 - 1

猜你喜欢

转载自blog.csdn.net/N2H4N2H4/article/details/82913667