for循环内,开多个线程处理数据,再合并数据,提升效率处理,提升1.5s。

Posted earlybridvic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了for循环内,开多个线程处理数据,再合并数据,提升效率处理,提升1.5s。相关的知识,希望对你有一定的参考价值。

直接复制一段代码,过后再看下具体运用的技术。

import com.example.tsfunproj.entity.*;
import com.example.tsfunproj.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@RestController
public class QuestionBankTitleController {

    @Autowired
    private FloorService floorService;

    @Autowired
    private QuestionBankService questionBankService;

    @Autowired
    private TitleService titleService;

    @Autowired
    private OptionService optionService;

    @Autowired
    private AnalyseService analyseService;

    @Autowired
    private AnswerService answerService;

    @Autowired
    private DidtitlesService didtitlesservice;

    @Autowired
    private IntofloortimeService intofloortimeService;

    @RequestMapping(value = "/questionBankTileLists")
    public BaseResponse questionBankTileLists(@RequestParam(value = "floorid", required = false) String floorid,
                                              @RequestParam(value="userid")String userid) {
        int firstcome = 1;
        Floor floor = floorService.selectByPrimaryKey(Integer.parseInt(floorid));
        int fid = floor.getFloorid();
        //获取到第几次进来再说吧。
        Intofloortime intofloortime = intofloortimeService.getByFandU(fid,userid);
        if(intofloortime!=null){
            firstcome = 0;
            intofloortime.setNumbertime(intofloortime.getNumbertime()+1);
            intofloortimeService.updateIntofloortime(intofloortime);
        }
        else if(intofloortime==null){
            firstcome = 1;
            Intofloortime intofloortime1 = new Intofloortime();
            intofloortime1.setFloorid(fid);
            intofloortime1.setUserid(userid);
            intofloortime1.setNumbertime(1);
            intofloortimeService.saveIntofloortime(intofloortime1);
        }
        Long startTwo = System.currentTimeMillis();
        String questionbankid = floor.getQuestionbankid();
        Questionbank qbMapper = questionBankService.selectByPrimaryKey(questionbankid);
        StringBuilder resultJson = new StringBuilder();
        resultJson.append("{ \"titleLists\":[");
        Long startOne = System.currentTimeMillis();
        if(firstcome == 1){
            List<Title> titleMappers = titleService.selectByQuestionBankid(qbMapper.getQuestionbankid());
            for(int i=0;i<titleMappers.size();i++){
                Didtitles didtitles = new Didtitles();
                didtitles.setUserid(userid);
                didtitles.setQuestionbankid(qbMapper.getQuestionbankid());
                didtitles.setTitleid(titleMappers.get(i).getTitleid());
                didtitlesservice.saveDidtitles(didtitles);
            }
        }
        Long endOne = System.currentTimeMillis();
        System.out.println("1ms:"+(endOne-startOne));
        startOne = System.currentTimeMillis();
        List<Didtitles> titlelists = didtitlesservice.getDidtitlesByQuestionid(qbMapper.getQuestionbankid());
        List<Title> titleAll = titleService.getAll();
        List<Option> optionAll = optionService.getAll();
        List<Answer> answerAll = answerService.getAll();
        List<Analyse> analyseAll = analyseService.getAll();
        endOne = System.currentTimeMillis();
        System.out.println("2ms:"+(endOne-startOne));
        startOne = System.currentTimeMillis();
        if (titlelists != null && titlelists.size() > 0) {
            List<List<Didtitles>> dititlesList = averageAssign(titlelists, 3);
            List<List<Title>> titleList = averageAssign(titleAll, 3);
            final CountDownLatch latch = new CountDownLatch(3);
            ExecutorService pool = Executors.newFixedThreadPool(3);
            List list = new ArrayList();
            try {
                for (int j = 0; j < dititlesList.size(); j++) {
                    Callable<Map<String, Object>> c1 = new CallableThread(heBing(dititlesList.get(j), titleList.get(j), optionAll, answerAll, analyseAll,qbMapper), latch);
                    Future<Map<String, Object>> f1 = pool.submit(c1);
                    list.add(f1);
                }
                latch.await();
                for (int i = 0; i < list.size(); i++) {
                    Future<Map<String, Object>> f1 = (Future<Map<String, Object>>) list.get(i);
                    resultJson.append(f1.get().get("sb").toString());
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        resultJson = resultJson.deleteCharAt(resultJson.length()-1);
        resultJson.append( "]}");
        endOne = System.currentTimeMillis();
        System.out.println("3ms:"+(endOne-startOne));
        BaseResponse response=new BaseResponse(StatusCode.Success);
        response.setMsg("返回题目列表成功");
        response.setDataTwo(resultJson);
        return response;
    }

    @RequestMapping(value="/getInputAnswer")
    public BaseResponse getInputAnswer(@RequestParam("questionbankid") String questionbankid,
                                       @RequestParam("titleid") String titleid,
                                       @RequestParam("userid") String userid){
        BaseResponse response=new BaseResponse(StatusCode.Success);
        String result = "";
        Didtitles didtitles =  didtitlesservice.getByUseridAndTitleidAndQb(userid,titleid,questionbankid);
        result = didtitles.getInputAnswer();
        response.setDataTwo(result);
        return response;
    }

    @RequestMapping(value = "/writeinputanswer", produces = {"text/html;charset=UTF-8"})
    public String writeinputanswer(@RequestParam("inputanswer") String inputanswer,
                                   @RequestParam("questionbankid") String questionbankid,
                                   @RequestParam("titleid") String titleid,
                                   @RequestParam("userid") String userid) {
        int rightornot = 0;
        Title title = titleService.selectByPrimaryKey(titleid);
        if(title.getOriginanswer().equals(inputanswer)){
            rightornot = 0;
        }
        else if(!title.getOriginanswer().equals(inputanswer)){
            rightornot = 1;
        }
        int resultFlag = didtitlesservice.updateDidtitlesByThreeParam(titleid, questionbankid, userid, inputanswer,rightornot);
        if (resultFlag > 0) {
            return "我的答案:" + inputanswer + "";
        }
        return "更新失败";
    }
    public static <T> List<List<T>> averageAssign(List<T> list,int n) {
        List<List<T>> result = new ArrayList<List<T>>();
        int remaider = list.size() % n;  //(先计算出余数)
        int number = list.size() / n;  //然后是商
        int offset = 0;//偏移量
        for (int i = 0; i < n; i++) {
            List<T> value = null;
            if (remaider > 0) {
                value = list.subList(i * number + offset, (i + 1) * number + offset + 1);
                remaider--;
                offset++;
            } else {
                value = list.subList(i * number + offset, (i + 1) * number + offset);
            }
            result.add(value);
        }
        return result;

    }
    public StringBuilder heBing(List<Didtitles> titlelists,List<Title>titleAll,List<Option> optionAll,List<Answer> answerAll,List<Analyse> analyseAll,Questionbank qbMapper ){
        StringBuilder resultJson = new StringBuilder();
        for (int i = 0; i < titlelists.size(); i++) {
            for (int j = 0; j < titleAll.size(); j++) {   //两个循环查找每一道题目
                if (titleAll.get(j).getTitleid().equals(titlelists.get(i).getTitleid())) {//对于每一道题目
                    String str = "";
                    if (titleAll.get(j).getTitletype().equals("1")) {
                        str = "单选题";
                    }
                    if (titleAll.get(j).getTitletype().equals("2")) {
                        str = "多选题";
                    }
                    if (titleAll.get(j).getTitletype().equals("3")) {
                        str = "不定项选择题";
                    }
                    if (titleAll.get(j).getTitletype().equals("4")) {
                        str = "问答题";
                    }
                    resultJson.append("{ \"titletype\":\"" + str + "\"," +
                            "\"stem\":\"" + titleAll.get(j).getStem() + "\",\"questionbankid\":\"");
                    resultJson.append( titlelists.get(i).getQuestionbankid() + "\",\"titleid\":\"");
                    resultJson.append( titlelists.get(i).getTitleid() + "\"");
                    List<Option> opts = new ArrayList<Option>();
                    for (int p = 0; p < optionAll.size(); p++) {
                        if (optionAll.get(p).getTitleid().equals(titlelists.get(i).getTitleid())) {
                            opts.add(optionAll.get(p));
                        }
                    }
                    Analyse ana = null;
                    for (int p = 0; p < analyseAll.size(); p++) {
                        if (analyseAll.get(p).getTitleid().equals(titlelists.get(i).getTitleid())) {
                            ana = analyseAll.get(p);
                        }
                    }
                    Answer ans = null;
                    for (int p = 0; p < answerAll.size(); p++) {
                        if (answerAll.get(p).getTitleid().equals(titlelists.get(i).getTitleid())) {
                            ans = answerAll.get(p);
                        }
                    }
                    resultJson.append( ",\"options\":\"");
                    for (int k = 0; k < opts.size(); k++) {
                        resultJson.append( opts.get(k).getOptionvalue() + "|");
                    }
                    resultJson = resultJson.deleteCharAt(resultJson.length()-1);
                    resultJson.append( "\"");
                    resultJson.append( ",\"answer\":\"");
                    resultJson.append(ans.getAnswervalue());
                    resultJson.append( "\"");
                    resultJson.append(",\"analyse\":\"");
                    resultJson.append(ana.getAnalysevalue());
                    resultJson.append("\",");
                    resultJson.append("\"");
                    resultJson.append("titlenumber\":\"");
                    resultJson.append(qbMapper.getTitlenumber() + "\",\"inputanswer\":\"");
                    resultJson.append(titlelists.get(i).getInputAnswer() + "\"},");
                }
            }
        }
        return  resultJson;
    }
}
class CallableThread implements Callable<Map<String,Object>> {
    StringBuilder sb;
    private Map<String, Object> map = new HashMap<String, Object>();//定义需要返回的map
    private final CountDownLatch latch;

    public CallableThread(StringBuilder sb, CountDownLatch latch) {
        this.sb = sb;
        this.latch = latch;
    }

    public Map<String, Object> call() throws Exception {
        try {
            //每个参数手动增加100
            map.put("sb", sb);
            System.out.println("线程:" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            latch.countDown();
        }
        return map;
    }
}

  

以上是关于for循环内,开多个线程处理数据,再合并数据,提升效率处理,提升1.5s。的主要内容,如果未能解决你的问题,请参考以下文章

for循环内线程池并发执行任务,等到子线程全部处理完任务,主线程在执行java的实现方式

for循环内的多处理

如何使用 for 循环组合多个数据帧?

测开面试 | 操作系统相关问题整理

python多线程

用C语言开多线程,想让多个相同的子线程同时运行,怎么实现