1. 开启线程执行for循环
//开启线程执行for循环
List<CusDtbAndRecycleParmas> outParamsList = new Vector<CusDtbAndRecycleParmas>();
2. 组装for循环中所需参数
//入参
Map<String,Object> inparams = new HashMap<String,Object>();
inparams.put("out",outParamsList);
inparams.put("coreInfoMap",coreInfoMap);
inparams.put("custUidMap",custUidMap);
inparams.put(BBK_ORG_ID,bbkOrgId);
inparams.put("grpCdParam",grpCdParam);
inparams.put("cardLvlCdMap",cardLvlCdMap);
inparams.put("RoleCodeMap",RoleCodeMap);
inparams.put("userNmMap",userNmMap);
inparams.put("markInfoMap",markInfoMap);
3.开始执行for循环
CallableBean callableBeanOut = new CallableBean(this,"loopOutParams", CallType.TWO,inparams);
ConcurrentUtil.processForNoRst(callableBeanOut, mainAccountList);
4.for循环执行方法 loopOutParanms 示例
public int loopOutParams(CallableBean callableBean,Object paramsObj) throws Exception{
String custUid = "";
String orgCardNbr = "";
DecimalFormat df = new DecimalFormat("0.00"); //转换为两位小数结尾
Map<String , String> mapInParmas = new HashMap<String, String>();
CusDtbAndRecycleParmas curParam = (CusDtbAndRecycleParmas) paramsObj;
CusDtbAndRecycleParmas tmpParam = curParam;
Map<String,Object> inparams = (Map<String,Object>)callableBean.getInParams();
List<CusDtbAndRecycleParmas> resultList = (List<CusDtbAndRecycleParmas>) inparams.get("out");
Map<String,CusDtbAndRecycleParmas> markInfoMap = (Map<String, CusDtbAndRecycleParmas>) inparams.get("markInfoMap");
Map<String,CusDtbAndRecycleParmas> coreInfoMap = (Map<String, CusDtbAndRecycleParmas>) inparams.get("coreInfoMap");
Map<String,List<String>> custUidMap = (Map<String, List<String>>) inparams.get("custUidMap");
Map<String, String> grpCdParam = (Map<String, String>) inparams.get("grpCdParam");
Map<String, String> cardLvlCdMap = (Map<String, String>) inparams.get("cardLvlCdMap");
Map<String, String> RoleCodeMap = (Map<String, String>) inparams.get("RoleCodeMap");
Map<String, String> userNmMap = (Map<String, String>) inparams.get("userNmMap");
String bbkOrgId = (String)inparams.get(BBK_ORG_ID);
custUid = curParam.getCustUid();
orgCardNbr = curParam.getCusCardNbr();
String cardGrdCd = curParam.getCardGrdCd();
mapInParmas.put("custUid", custUid);
if(coreInfoMap.containsKey(curParam.getCustUid())) {
CusDtbAndRecycleParmas coreInfoParam = coreInfoMap.get(curParam.getCustUid());
//初始化tmpParam
tmpParam.setCustNm(coreInfoParam.getCustNm());
tmpParam.setSex(coreInfoParam.getSex());
tmpParam.setMonthAss(coreInfoParam.getMonthAss() != null ? coreInfoParam.getMonthAss() : "0.00");
tmpParam.setTimeAss(coreInfoParam.getTimeAss() != null ? coreInfoParam.getTimeAss() : "0.00");
tmpParam.setThirdAss(coreInfoParam.getThirdAss() != null ? coreInfoParam.getThirdAss() : "0.00") ;
tmpParam.setDayAcsMmkv(coreInfoParam.getDayAcsMmkv() != null ? coreInfoParam.getDayAcsMmkv() : "0.00");
tmpParam.setDayAcsTmkv(coreInfoParam.getDayAcsTmkv() != null ? coreInfoParam.getDayAcsTmkv() : "0.00");
tmpParam.setLastMonthAcsMmkv(coreInfoParam.getLastMonthAcsMmkv() != null ? coreInfoParam.getLastMonthAcsMmkv() : "0.00");
tmpParam.setLastMonthAcsTmkv(coreInfoParam.getLastMonthAcsTmkv() != null ? coreInfoParam.getLastMonthAcsTmkv() : "0.00");
}
List<String> subList = custUidMap.get(custUid);
if(!subList.isEmpty()) {
....
resultList.add(tmpParam);
return 1;
}
4.线程基础类 BaseCallable
package com.cmb.dw.rtl.utils.concurrent;
import org.apache.log4j.Logger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**线程基础类
*/
public class BaseCallable implements Callable {
private static final Logger LOGGER = Logger.getLogger(BaseCallable.class);
private CallableBean callableBean; //callable 调用bean
private Object paramsObj; //for循环list中单个对象
public BaseCallable(CallableBean callableBean) {
this.callableBean = callableBean;
}
public BaseCallable(CallableBean callableBean, Object paramsObj) {
this.callableBean = callableBean;
this.paramsObj = paramsObj;
}
@Override
public Object call()throws NoSuchMethodException,IllegalAccessException,InvocationTargetException{
Object callObj = callableBean.getCallCls();
String methodNm = callableBean.getMethodNm();
CallType callType = callableBean.getCallType();
LOGGER.info("调用callable开始,调用类:" + callObj + "调用方法" + methodNm + "调用类型" + callType);
long begin = System.currentTimeMillis();
Object result = null;
Method method;
switch(callType){
case ONE:
method = callObj.getClass().getMethod(methodNm,CallableBean.class);
result = method.invoke(callObj,callableBean);
break;
case TWO:
method = callObj.getClass().getMethod(methodNm,CallableBean.class,Object.class);
result = method.invoke(callObj,callableBean,paramsObj);
break;
default:
break;
}
long end = System.currentTimeMillis();
LOGGER.info("调用callable结束,用时" + (end - begin) + "ms");
return result;
}
}
5. 并发框架工具
import com.cmb.framework.core.container.SpringContainer;
import org.apache.log4j.Logger;
import org.springframework.core.task.TaskExecutor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**并发框架工具
*/
public class ConcurrentUtil {
private static final Logger LOGGER = Logger.getLogger(ConcurrentUtil.class);
private static TaskExecutor taskExecutor = null;
static {
getTaskExecutor();
}
/**
* 获取线程池
*
* @return
*/
private static TaskExecutor getTaskExecutor() {
if (null == taskExecutor) {
taskExecutor = (TaskExecutor) SpringContainer.getBean("taskExecutor");
}
return taskExecutor;
}
/**
* 需要结果
* @param callList callable 的list
* @return
* @throws ExecutionException
* @throws InterruptedException
*/
public static List<Object> processForRst(List<CallableBean> callList) throws ExecutionException,InterruptedException{
List<FutureTask> futureTaskList = new ArrayList<FutureTask>();
for(CallableBean callableBean : callList){
BaseCallable baseCallable = new BaseCallable(callableBean);
FutureTask futureTask = new FutureTask(baseCallable);
taskExecutor.execute(futureTask);
futureTaskList.add(futureTask);
}
List<Object> rstList = new ArrayList<Object>();
for(FutureTask futureTask : futureTaskList){
Object result = futureTask.get();
rstList.add(result);
}
return rstList;
}
/**
* 直接调用获取结果,可以日志使用
* @param callableBean
* @return
* @throws ExecutionException
* @throws InterruptedException
*/
public static Object process(CallableBean callableBean) throws ExecutionException,InterruptedException{
BaseCallable baseCallable = new BaseCallable(callableBean);
FutureTask futureTask = new FutureTask(baseCallable);
taskExecutor.execute(futureTask);
return futureTask.get();
}
/**不需要结果
* for循环使用
* @param callableBean 基础类
* @param list for循环的list
* @param <T> list类的类型
* @throws ExecutionException
* @throws InterruptedException
*/
public static <T> void processForNoRst(CallableBean callableBean, List<T> list) throws ExecutionException,InterruptedException{
List<FutureTask<Object>> futureTaskList = new ArrayList<FutureTask<Object>>();
for (final T t : list) {
BaseCallable baseCallable = new BaseCallable(callableBean, t);
FutureTask futureTask = new FutureTask(baseCallable);
taskExecutor.execute(futureTask);
futureTaskList.add(futureTask);
}
for (FutureTask futureTask : futureTaskList) {
//futureTask.get(3000, TimeUnit.MILLISECONDS); TimeoutException
futureTask.get();
}
}
}
5. callable 调用 bean
/**callable 调用bean
*/
public class CallableBean {
private Object callCls; //调用类,比如service
private String methodNm; //调用类的方法
private CallType callType; //调用方法的类型 枚举器 CallType.java
private Object inParams; //调用方法入参
public CallableBean(Object callCls, String methodNm, CallType callType, Object inParams) {
this.callCls = callCls;
this.methodNm = methodNm;
this.callType = callType;
this.inParams = inParams;
}
public Object getCallCls() {
return callCls;
}
public void setCallCls(Object callCls) {
this.callCls = callCls;
}
public String getMethodNm() {
return methodNm;
}
public void setMethodNm(String methodNm) {
this.methodNm = methodNm;
}
public CallType getCallType() {
return callType;
}
public void setCallType(CallType callType) {
this.callType = callType;
}
public Object getInParams() {
return inParams;
}
public void setInParams(Object inParams) {
this.inParams = inParams;
}
}
6. callable 调用类型(枚举)
/**callable 调用类型 枚举器
*/
public enum CallType {
ONE, //使用一个线程
TWO, //for循环中每个循环使用一个线程
THREE,
FOUR
}