Semaphore(信号量) 用来控制同时访问特定资源的线程数量。可以起到限流的作用。它与之前写到的Guava API 中的令牌桶 RateLimiter的区别在于,令牌桶是控制了最终能进入访问资源的恒定流量。会抛弃掉一些过剩流量的进入。而Semaphore 保证的是进入流量的恒定速率,这些流量最终都可以进入访问资源,只是已一定的速率。
public class SemaphoreTest2 {
final Semaphore_copy sc = new Semaphore_copy(2,true);
private static class Semaphore_copy extends Semaphore{
public Semaphore_copy(int permits,boolean fair){
super(permits, fair);
}
@Override
protected Collection<Thread> getQueuedThreads() {
List<Thread> list = new ArrayList<>(super.getQueuedThreads());
Collections.reverse(list);
return list;
}
}
public void dosomethings(){
try {
sc.acquire();
System.out.println(Thread.currentThread().getName()+" get the Semaphore>>> "+sc.getQueuedThreads().stream().map(t -> t.getName()).collect(Collectors.toList())+" are waiting...");
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
sc.release();
}
}
public static void main(String[] args) {
SemaphoreTest2 st = new SemaphoreTest2();
ThreadPoolExecutor pool = new ThreadPoolExecutor(4, 8, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20));
for(int i = 0;i<20;i++){
pool.execute(new Thread(()->st.dosomethings()));
}
pool.shutdown();
}
}
以上代码运行结果
信号量控制为2,线程池中核心线程数为4,但是每次只能允许两个线程获得信号得以消费,其余得等待获得信号量