• 请求合并实战版本


    package com.example.demo.concurrent.requestmerge;
    
    import com.example.demo.schedule.entity.ISysJobRepository;
    import com.example.demo.schedule.entity.SysJobPO;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.concurrent.*;
    
    
    /**
     * 请求合并:
     * 高并发调用这里的服务,针对查询对请求进行合并,
     */
    @Service(value="JobServiceImpl2")
    public class JobServiceImpl2 implements IJobService {
        class Request{
            Integer jobId;
            CompletableFuture<SysJobPO> result;
        }
        //存放并发线程调用的参数
        private LinkedBlockingQueue<Request> requestQue=new LinkedBlockingQueue<>();
        @Autowired
        private ISysJobRepository jobRepository;
    
        /**
         * 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次
         * 执行顺序在@Autowired之后
         */
        @PostConstruct
        public void init() {
            System.out.println("合并请求");
            ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
            //参数1运行的任务,参数2执行时间0立即执行,参数3间隔时间,参数4时间单位
            //每10毫秒批量查询一次队列
            threadPool.scheduleAtFixedRate(() -> {
                ArrayList<Request> requestList = new ArrayList<Request>();
                List<Integer> jobIdList = new ArrayList<Integer>();
                int size = requestQue.size();
                if(size==0)
                    return;
                System.out.println("批量查询大小"+size);
    
                for (int i = 0; i <size; i++) {
                    Request request = requestQue.poll();
                    requestList.add(request);
                    jobIdList.add(request.jobId);
                }
                //批量查询出所有结果
                List<SysJobPO> jobList = getSysJobListByJobIdList(jobIdList);
                //讲结果转化为map<k,v>  key为jobId value为查询的结果
                HashMap<Integer,SysJobPO> map = new HashMap<>();
                for (SysJobPO job : jobList) {
                    map.put(job.getJobId(), job);
                }
                //讲结果分发给每个线程,即分发给CompletableFuture,根据jobid分发
                for (Request request : requestList) {
                    request.result.complete(map.get(request.jobId));
                }
            }, 0, 10, TimeUnit.MILLISECONDS);
        }
    
        @Override
        public SysJobPO selectByPrimaryKey(Integer jobId) {
            Request request=new Request();
            CompletableFuture<SysJobPO> futureResult = new CompletableFuture<>();
            request.jobId=jobId;
            request.result=futureResult;
            requestQue.add(request);
            SysJobPO job=null;
            try {
                //阻塞至futureResult.complete()方法
                job = futureResult.get();
            } catch (InterruptedException | ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return job;
        }
    
        @Override
        public List<SysJobPO> getSysJobListByJobIdList(List<Integer> jobIds) {
            return jobRepository.findByJobIdIn(jobIds);
        }
    }
    View Code
    package com.example.demo.concurrent.requestmerge;
    
    import com.example.demo.schedule.entity.SysJobPO;
    
    import java.util.List;
    
    public interface IJobService {
        SysJobPO selectByPrimaryKey(Integer jobId);
    
        List<SysJobPO> getSysJobListByJobIdList(List<Integer> jobIds);
    }
    View Code
    package com.example.demo.concurrent;
    
    import com.example.demo.DemoApplication;
    import com.example.demo.concurrent.requestmerge.IJobService;
    import com.example.demo.schedule.entity.SysJobPO;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import javax.annotation.Resource;
    import java.io.IOException;
    import java.util.concurrent.CountDownLatch;
    
    //请求合并测试
    @SpringBootTest(classes= DemoApplication.class)
    @WebAppConfiguration
    @RunWith(SpringRunner.class)
    public class SpringConcurrentTest {
        @Resource(name="JobServiceImpl2")
        private IJobService jobService;
        @Test
        public void test1(){
            SysJobPO job = jobService.selectByPrimaryKey(2);
            System.out.println(job);
        }
    
        @Test
        public void bingfa() throws InterruptedException, IOException {
            CountDownLatch countDownLatch=new CountDownLatch(1000);
            for (int i = 0; i <1000; i++) {
                final int j=i;
                new java.lang.Thread(() -> {
                    try {
                        countDownLatch.await();
                        SysJobPO job = jobService.selectByPrimaryKey(j);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                ).start();
                countDownLatch.countDown();
            }
            System.in.read();
        }
    }
    View Code
  • 相关阅读:
    更新增加一个门店ID字段的值
    测试成功,修改能运行代码--待优化
    奶粉运营,跑数据三个模板。
    子查询返回多条报错误
    分析跑数口径与表内在关系逻辑
    NAVICAT PREMIUM 初识
    长沙生活
    金蝶用户操作
    EXCEL对比重复数据
    处理链长期检查问题
  • 原文地址:https://www.cnblogs.com/sunny-miss/p/13057754.html
Copyright © 2020-2023  润新知