package com.chushang.common.core.util;

import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @author by zhaowenyuan create 2022/7/18 10:14
 * 并发测试
 */
@Slf4j
public class ConcurrencyUtilTest {
    // 请求总数
    public static int clientTotal = 10000000;

    // 同时并发执行的线程数
    public static int threadTotal = 1000;

    public static void main(String[] args) {
        Map<String, Integer> map = new ConcurrentHashMap<>();
        try {
            insert(map);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("{}",map);
        log.info("{}",map.values().stream().max(Integer::compareTo).orElse(0));
        log.info("{}", map.values().stream().count());
    }

    public static void insert(Map<String, Integer> map) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(threadTotal);
        //信号量，此处用于控制并发的线程数
        final Semaphore semaphore = new Semaphore(threadTotal);
        //闭锁，可实现计数器递减
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(() -> {
                try {
                    //执行此方法用于获取执行许可，当总计未释放的许可数不超过200时，
                    //允许通行，否则线程阻塞等待，直到获取到许可。
                    semaphore.acquire();

//                    /**
//                     * 放置具体的 待测试并发逻辑
//                     */
//                    String numId = IdUtils.getTimeId();
//                    map.merge(numId, 1, Integer::sum);

                    //释放许可
                    semaphore.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            });
        }
        //线程阻塞，直到闭锁值为0时，阻塞才释放，继续往下执行
        countDownLatch.await();
        executorService.shutdown();
    }
}
