单机限流的几种方式

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wangjianhua_love/article/details/81530366
/**
 * 原子计数限流方式
 * 简单粗暴的限流方式,没有平滑处理,需要根据场景使用
 */
public class AtomicLimit {
    private AtomicInteger requestCount=new AtomicInteger(0);

    public void doRequest(String threadName){
        try {
            if (requestCount.incrementAndGet() > 10) {
                System.out.println(threadName + "请求过多请稍后重试");
            } else {
                System.out.println(threadName + "您的请求已经处理");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //mark 正常业务逻辑处理结束
            }
        }finally {
            requestCount.decrementAndGet();
        }
    }
/**
 * 利用信号量方式限流
 */
public class ExcutorSignal {
    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(20);
        //只能5个线程同时访问
        final Semaphore semp = new Semaphore(5);
        for (int i = 0; i < 20; i++) {
            final int taskNo = i;
            Runnable run = new Runnable() {
                @Override
                public void run() {
                    try {
                        semp.acquire();//获取许可
                        String name = Thread.currentThread().getName();
                        System.out.println("开始" + name + "_" + taskNo);
                        Thread.sleep((long) (Math.random() * 10000));
                        semp.release();//访问完后释放
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            exec.execute(run);
        }
    }
}
/**
 * 令牌桶,主要限制流入
 * 限流,多的请求直接拒绝
 * 可以针对方法级别配置
 */
public class TrafficShapper {
    private RateLimiter rateLimiter = RateLimiter.create(10);
    public void doRequest(String threadName) {
        boolean isAcquired = rateLimiter.tryAcquire(1, 3000L, TimeUnit.MICROSECONDS);//rateLimiter.tryAcquire();
        if (isAcquired) {
            System.out.println(threadName + ":调用成功");
        } else {
            System.out.println(threadName + ":当前调用人数过多,请稍后重试");
        }
    }

    public static void main(String[] args) {
        final TrafficShapper shapper = new TrafficShapper();
        final CountDownLatch latch = new CountDownLatch(1);
        final Random random = new Random(10);
        for (int i = 0; i < 20; i++) {
            final int finalT = i;
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        latch.await();
                        int sleepTime = random.nextInt(1000);
                        Thread.sleep(sleepTime);
                        shapper.doRequest("t-" + finalT);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
        latch.countDown();
    }

}

CountDownLatch latch=new CountDownLatch(1);//mark 保证线程同一时刻启动
latch.await();
latch.countDown();//当前计数为0则不执行操作,当计数从>0变成0后,所有线程同时启动

展开阅读全文

没有更多推荐了,返回首页