使用ExecutorService、Callable、Future實現有返回結果的多執行緒 應用例項
阿新 • • 發佈:2019-01-06
以下是實踐中應用到的多執行緒:
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裡進行,有排重功效
}
}
}