今天有一個接口20s 才能展示出來數據,這怎么可以領導直接讓我去處理這個接口,處理不出來就不要下班了
我心中一緊 趕緊去看這是哪個垃圾寫出來的代碼
瀏覽了一下代碼發現 需求是這樣子的 后台請求一個地址 返回了一個list集合,我拿着這個list 集合對象的主鍵,再去調用查看詳情接口,拼接到原來的對象上。最后在合並拼接上參數的對象集合。
以前的兄弟直接for循環調用,數據量不大 130多條數據 但是也需要20秒(1個接口調用150毫秒,幫大家算出來了)。
這怎么行,祭出大殺器,多線程。
我們需要用callable 的線程方法 因為我們還需要將返回值 給他拼回去 代碼如下
package com.zhgw.dev.pioc.utils; import com.alibaba.fastjson.JSONObject; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; public class PersionThread implements Callable { /** 數據集合 */ private List<PersionDTO> list; /** 權限 */ private String token; /** 每個線程處理的起始數據 */ private CountDownLatch begin; /** 每個線程處理的結束數據 */ private CountDownLatch end; public PersionThread() { } public PersionThread(List<PersionDTO> list, CountDownLatch begin, CountDownLatch end,String token) { this.list = list; this.begin = begin; this.end = end; this.token = token; } @Override public List<PersionDTO> call() throws Exception { try { if (list != null && !list.isEmpty()) { // testBatchInsertMapper.batchInsert(list); List<PersionDTO> PersionDTOArrayList = new ArrayList<>(); int size = list.size(); for (PersionDTO PersionDTO :list) { String personString = HttpUtils.httpPostForm("http://www.baidu.com" + "?token=" + token + "&oid=" + PersionDTO.getInspectoroid(), null, false, "160"); } //System.out.println("線程"+JSONObject.toJSONString(PersionDTOArrayList)); return PersionDTOArrayList; } // 執行完讓線程直接進入等待 begin.await(); } catch (Exception e) { e.printStackTrace(); } finally { // 當一個線程執行完 了計數要減一不然這個線程會被一直掛起 end.countDown(); } return null; } }
執行多線程的方法
public List batchInsertByThread(List<PersionDTO> list, String token){ if (list == null || list.isEmpty()) { return null; } // 一個線程處理6條數據 int count = 7; // 數據集合大小 int listSize = list.size(); // 開啟的線程數 int runSize = (listSize / count) + 1; // 存放每個線程的執行數據 List<PersionDTO> newList = null; // 創建一個線程池,數量和開啟線程的數量一樣 ExecutorService executor = Executors.newFixedThreadPool(runSize); // 創建兩個個計數器 CountDownLatch begin = new CountDownLatch(1); CountDownLatch end = new CountDownLatch(runSize); List<Future< List<PersionDTO>>> futures = new ArrayList<Future< List<PersionDTO>>>(); // 創建一個存儲所有返回值的list List<PersionDTO> listAll = Collections.synchronizedList(new ArrayList<PersionDTO>()); for (int i = 0; i < runSize; i++) { /* 計算每個線程執行的數據 */ if ((i + 1) == runSize) { int startIdx = (i * count); int endIdx = list.size(); newList = list.subList(startIdx, endIdx); } else { int startIdx = (i * count); int endIdx = (i + 1) * count; newList = list.subList(startIdx, endIdx); } PersionThread PersionThread = new PersionThread(newList, begin, end, token); futures.add(executor.submit(PersionThread)); } begin.countDown(); //System.out.println("submit"+ JSONObject.toJSONString(submit)); try { for(Future< List<PersionDTO>> future : futures){ //合並操作 List<PersionDTO> PersionDTOS = null; try { PersionDTOS = future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } listAll.addAll(PersionDTOS); } //System.out.println(JSONObject.toJSONString(listAll)); end.await(); } catch (InterruptedException e) { e.printStackTrace(); } executor.shutdown(); return listAll; }
調用線程的方法
public static void main(String[] args) { R<List<PersonnelGPSDTO>> listR = personnelGPS(); System.out.println(listR);
