java 并发控制_高并发系统限流操作之Semaphore实现可变并发数控制

Semaphore内部主要通过AQS(AbstractQueuedSynchronizer)实现线程的管理。

信号量通过使用计数器来控制对共享资源的访问。如果计数器大于零,则允许访问。如果为零,则拒绝访问。计数器的计数是允许访问共享资源的许可。

常用于限制可以访问某些资源的线程数目。

本例子通过增加与减少许可证数来动态控制线程数目,即控制线程并发。

核心源码:

import java.util.concurrent.Semaphore;

/**

* 可变许可证

*/

public class AdjustableSemaphore {

/**

* The Semaphore.

*/

private final ResizeableSemaphore semaphore = new ResizeableSemaphore();

/**

* 最大许可证数

*/

private int maxPermits = 0;

/**

* Instantiates a new Adjustable semaphore.

*/

public AdjustableSemaphore() {

}

/**

* 设置最大许可证数

*

* @param newMax 最大许可证数

*/

public synchronized void setMaxPermits(int newMax) {

if (newMax < 1) {

throw new IllegalArgumentException("Semaphore size must be at least 1, was:" + newMax);

}

int delta = newMax - this.maxPermits;

if (delta == 0) {

return;

} else if (delta > 0) {

//多释放几次,就可以达到信号量动态增加的效果了

this.semaphore.release(delta);

} else {

delta *= -1;

//减少信号量

this.semaphore.reducePermits(delta);

}

this.maxPermits = newMax;

}

/**

* 获取当前可用的许可证数量

*

* @return 当前可用的许可证数量

*/

public int availablePermits() {

return this.semaphore.availablePermits();

}

/**

* 释放1个许可证

*/

public void release() {

this.semaphore.release();

}

/**

* 当前线程尝试去获取1个许可证。

*

* 此过程是非阻塞的,它只是在方法调用时进行一次尝试。

*

* 如果当前线程获取了1个可用的许可证,则会停止等待,继续执行,并返回true。

*

* 如果当前线程没有获得这个许可证,也会停止等待,继续执行,并返回false。

*

* @return the boolean

*/

public boolean tryAcquire() {

return this.semaphore.tryAcquire();

}

/**

* 可调节信号量

*/

private static final class ResizeableSemaphore extends Semaphore {

/**

* Instantiates a new Resizeable semaphore.

*/

ResizeableSemaphore() {

super(0);

}

/**

* 减少许可证

*

* @param reduction 减少许可证的数量

*/

@Override

protected void reducePermits(int reduction) {

super.reducePermits(reduction);

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值