Java 如何用队列解决高并发访问接口的问题?

看你这代码没返回值,所以你可以加个MQ试试。将请求参数封装到MQ中,路由规则可以看你请求参数,然后异步去消费。如果想通过java内存来实现,首先要保证你的服务只部署在单台机器上,然后我写了一个,你可以参考一下,应该会有bug,没细测

public class App{

    // 缓存
    private static final ConcurrentHashMap<String,Future<Long>> cache = new ConcurrentHashMap<>();
    // 缓存有效期
    private static final ConcurrentHashMap<String,String> cachePeriod = new ConcurrentHashMap<>();

    public static void main( String[] args ) throws ExecutionException, InterruptedException {

        for (int i = 0; i< 10;i++){
            Random r = new Random();
            String param = String.valueOf(i);
            App app = new App();
            app.compute(param);
        }

        new Thread(() -> {
            while (cachePeriod.size() > 0){
                for (String key : cachePeriod.keySet()) {
                    Long period = Long.valueOf(cachePeriod.get(key));
                    if (System.currentTimeMillis() / 1000 > period){
                        cachePeriod.remove(key);
                        cache.remove(key);
                    }
                }
            }
        }).start();

        while (cache.size() > 0){
            for (Map.Entry<String, Future<Long>> entry : cache.entrySet()) {
                System.out.println(entry.getKey() + "===" + entry.getValue().get());
                Thread.sleep(500);
            }
            System.out.println("=======================");
        }


    }


    /**
     * 数据库底层保存成功后返回数据记录ID
     * 将参数作为key保存到cache中
     * @param param 请求参数
     * @return Long 数据唯一标识
     */
    public Long compute(final String param){

        while (true){
            // 判断之前是否已处理过
            Future<Long> f = cache.get(param);
            // 未处理过
            if(f == null){
                // 封装处理请求操作
                Callable<Long> eval = () -> {
                    Long id = null;
                    //判断数据库是否有记录
                    if(!checkDbExist(param)){
                        //模拟数据库插入操作
                        id = dbInsert(param);
                    }
                    return id;
                };
                // 保存到缓存中并执行
                FutureTask<Long> ft = new FutureTask<>(eval);
                // 设置缓存有效期10秒
                cachePeriod.put(param,String.valueOf((System.currentTimeMillis() / 1000 + 10)));
                f = cache.putIfAbsent(param,ft);
                if(f == null){
                    f = ft;
                    ft.run();
                }
            }

            // 返回处理结果(数据记录ID)
            // 超时时间设置300毫秒
            try {
                return f.get(300,TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                cache.remove(f,param);
                f.cancel(true);
            } catch (ExecutionException e) {
                cache.remove(f,param);
                f.cancel(true);
            } catch (TimeoutException e) {
                cache.remove(f,param);
                f.cancel(true);
            }

        }
    }

    private Long dbInsert(String param) {
        Random r = new Random();
        return Long.valueOf(r.nextInt(20));
    }

    private boolean checkDbExist(String param) {
        if(Integer.valueOf(param) % 2 == 0){
            return true;
        }
        return false;
    }
}

 



这里给大家推荐一个在线软件复杂项交易平台:米鼠网 https://www.misuland.com

米鼠网自成立以来一直专注于从事软件项目人才招聘软件商城等,始终秉承“专业的服务,易用的产品”的经营理念,以“提供高品质的服务、满足客户的需求、携手共创双赢”为企业目标,为中国境内企业提供国际化、专业化、个性化、的软件项目解决方案,我司拥有一流的项目经理团队,具备过硬的软件项目设计和实施能力,为全国不同行业客户提供优质的产品和服务,得到了客户的广泛赞誉。

最新项目