1. 程式人生 > >使用ExecutorService、Callable、Future實現有返回結果的多執行緒 應用例項

使用ExecutorService、Callable、Future實現有返回結果的多執行緒 應用例項

  以下是實踐中應用到的多執行緒:

   1、controller程式碼:


    @RequestMapping(value = "/getTraingingUsersByTrainingIds", method = {RequestMethod.GET, RequestMethod.POST})
    public void getTraingingUsersByTrainingId(@RequestParam(value = "trainingIds", required = true) String trainingIds) {
        try {
            trainingService.getTraingingUsersByTrainingIdsParallel(jsonObject, trainingIds);
        } catch (Exception e) {
            logger.info("根據培訓班id獲取參培人員失敗", e);
        }
    }

2、service類,程式碼:

//執行緒池變數定義部分,定義預設是3個執行緒,且new ThreadFactory()用於自動銷燬結束的執行緒,避免伺服器關閉時,這個執行緒還存在於作業系統裡。
//導致伺服器埠啥的,仍被佔用,不能完全關閉,進而也影響下一次的重啟。還得手動殺執行緒等操作。
private static final ExecutorService threadPool = Executors.newFixedThreadPool(3, new ThreadFactory() {
        public Thread newThread(Runnable r) {
            Thread s = Executors.defaultThreadFactory().newThread(r);
            s.setDaemon(true);
            return s;
        }
    } );

//呼叫多執行緒部分的實現方法
public List getTraingingUsersByTrainingIdsParallel(JSONObject jsonObject, String trainingIds) {
        String arrtrainingIds [] = trainingIds.split(",");
          Map<HashMap, Boolean> map = new ConcurrentHashMap<>(); // 用於裝載返回值物件,並且能夠排重
       
       List<Future> futureList = new ArrayList<>();
        for (String trainingId : arrtrainingIds) {
            Training4ThreadService ytts = new Training4ThreadService(ybsTrainingMapper, map, Integer.parseInt(trainingId));
            Future future = threadPool.submit(ytts);
            futureList.add(future);
        }
        //主執行緒結束,等待其他執行緒處理結束時間是30秒,否則報執行時異常
        for(Future future : futureList){
            try {
                future.get(30, TimeUnit.SECONDS);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
//將map的key轉換為List,返回
return new ArrayList<>(map.keySet());
    }

3 執行緒物件類Training4ThreadService的程式碼如下:

public class Training4ThreadService  implements Runnable{


private List<HashMap> getListUsersByTrainingId(Integer trainingId) {
List<HashMap> ybsUserList = Lists.newArrayList();
Integer iFlag = 0; 
...
if (iFlag == 1) {      
ybsUserList = getYbsTrainingSetPersonSetByTrainingId(trainingId);
} else if(iFlag == 2) { 
Map<String,String> map =  com.beust.jcommander.internal.Maps.newHashMap();
...
map.put("trainingId",trainingId.toString());
ybsUserList = getYbsTrainingSetRangeSetByTrainingId(map);
}
return ybsUserList;
}


@Override
public void run() {//執行緒裡執行入口
List<HashMap>  ybsUserList = getListUsersByTrainingId(trainingId);//業務處理方法,根據實際情況進行定義,處理
//放入到maps
for (HashMap hm :ybsUserList) {
maps.put(hm, true);//放入map裡進行,有排重功效
}
}

}