1:新建Task类
public class Task implements Callable<TaskResult> {
/** 任务id **/
private String taskId = Thread.currentThread().getName();
/** 任务名称 **/
private String taskName = Thread.currentThread().getName();
/** 任务服务 **/
private TaskService taskService;
/** 任务执行数据列表 **/
private List<?> dataList;
public Task(TaskService taskService, List<?> dataList) {
this(taskService, dataList, null, null);
}
public Task(TaskService taskService, List<?> dataList, String taskId) {
this(taskService, dataList, taskId, null);
}
public Task(TaskService taskService, List<?> dataList, String taskId, String taskName) {
this.taskId = taskId;
this.taskName = taskName;
this.dataList = dataList;
this.taskService = taskService;
}
@Override
public TaskResult call() throws Exception {
TaskResult result = new TaskResult();
result.setTaskId(taskId);
result.setTaskId(taskName);
if(CollectionUtils.isEmpty(dataList)){
result.setPlanNum(0);
result.setSuccNum(0);
result.setRetValue(TaskResult.SUCCESS);
result.setErrorCode("999999");
result.setErrorMsg("没有可执行数据列表");
return result;
}
int planNum = dataList.size();
result.setPlanNum(planNum);
try {
//执行业务方法
int succNum = taskService.execute(dataList);
result.setSuccNum(succNum);
result.setRetValue(TaskResult.SUCCESS);
result.setErrorCode("000000");
result.setErrorMsg("执行成功");
}
catch (Exception e) {
e.printStackTrace();
result.setPlanNum(planNum);
result.setRetValue(TaskResult.FAIL);
result.setErrorCode("900000");
result.setErrorMsg(e.getMessage());
}
return result;
}
}
2:创建线程执行器工具类单例
/**
*
* 创建线程执行器工具类单例
*/
public class TaskUtil {
/** 实例 **/
private static TaskUtil instance;
/** 线程服务 **/
private ExecutorService executorService;
/** 最大线程数量 **/
private static final int MAX_POOL_SIZE = 20;
private static final Logger logger = LoggerFactory.getLogger(TaskUtil.class);
/** 单例模式 **/
private TaskUtil() {
}
public synchronized static TaskUtil getInstance() {
if (instance == null) {
instance = new TaskUtil();
}
return instance;
}
/**
*
* @title: doFixTask
* @author
* @description: 执行固定任务,每个任务一个线程
* @date 2015-4-29 下午3:37:25
* @param taskList
* @throws Exception
* @throws
*/
public void doFixTask(List<Task> taskList) throws Exception {
if (taskList.isEmpty()) {
logger.warn("没有需要处理的任务列表");
return;
}
try {
int fixPoolSize = taskList.size();
if(fixPoolSize > MAX_POOL_SIZE){
fixPoolSize = MAX_POOL_SIZE;
}
boolean stop = false;
// 创建线程池
executorService = createFixThreadPool(fixPoolSize);
List<Future<TaskResult>> futureList = new ArrayList<Future<TaskResult>>();
for (int i = 0; i < taskList.size(); i++) {
Future<TaskResult> future = executorService.submit(taskList.get(i));
futureList.add(future);
}
List<TaskResult> taskResultList = new ArrayList<TaskResult>();
for (int i = 0; i < futureList.size(); i++) {
Future<TaskResult> future = futureList.get(i);
taskResultList.add(future.get());
}
for (int i = 0; i < taskResultList.size(); i++) {
TaskResult taskResult = taskResultList.get(i);
String retValue = taskResult.getRetValue();
if (TaskResult.FAIL.equals(retValue)) {
stop = true;
}
String taskId = taskResult.getTaskId();
String taskName = taskResult.getTaskName();
int succNum = taskResult.getSuccNum();
int planNum = taskResult.getPlanNum();
String errorCode = taskResult.getErrorCode();
String errorMsg = taskResult.getErrorMsg();
logger.info(">>【执行结果】" + retValue + ">>【taskId】" + taskId + ">>【taskName】" + taskName + ">>【计划执行数量】"
+ planNum + ">>【成功执行数量】" + succNum + ">>【错误代码】" + errorCode + ">>【错误信息】" + errorMsg);
}
if (stop) {
throw new Exception("the task execute failed");
}
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
finally {
// 关闭线程池
shutdown(executorService);
}
}
/**
*
* @title: createFixThreadPool
* @author
* @description: 创建固定任务数量线程池
* @date 2015-4-29 下午4:05:26
* @param fixPoolSize
* @return
* @throws
*/
ExecutorService createFixThreadPool(int fixPoolSize) {
return Executors.newFixedThreadPool(fixPoolSize);
}
/**
*
* @title: shutdown
* @author
* @description: 关闭线程池
* @date 2015-4-29 下午4:06:16
* @param executorService
* @throws
*/
void shutdown(ExecutorService executorService) {
executorService.shutdown();
}
}
3:创建任务返回对象
public class TaskResult implements Serializable {
/**
* @fields serialVersionUID : 串行号
*/
private static final long serialVersionUID = -8958263539520324929L;
/** 任务成功 **/
public static final String SUCCESS = "0";
/** 任务失败 **/
public static final String FAIL = "1";
/** 任务ID **/
public String taskId;
/** 任务名称 **/
public String taskName;
/** 任务返回标识 **/
public String retValue;
/** 错误代码 **/
public String errorCode;
/** 错误信息 **/
public String errorMsg;
/** 计划执行数量 **/
public int planNum;
/** 实际成功数量 **/
public int succNum;
//属性get set 方法
}
4:创建多线程任务服务类接口
public interface TaskService {
public int execute(List<?> list) throws Exception;
}
5:创建任务服务类
@Service("com.qw.modules.BusiTaskService")
public class BusiTaskService implements TaskService, Serializable {
public int execute(List<?> list) {
batchExecuteBusi(list);
logger.info(Thread.currentThread().getName() + ">>>>【线程合计执行】>>>>>" + list.size());
return list.size();
}
/**
* 业务代码
* @param list
*/
public void batchExecuteBusi(List<?> list){
}
}
6:调用执行器
private void doCallExecute(List<xxxxx> list) {
logger.info("xxxx 开始:");
//分批多线程处理
// 创建任务列表
List<Task> taskList = new ArrayList<Task>();
if(null!=list&&list.size()>0){
int pointsDataLimit = 10000;//限制条数
Integer size = list.size();
//判断是否有必要分批
if(pointsDataLimit<size){
int part = size/pointsDataLimit;//分批数
System.out.println("共有 : "+size+"条,!"+" 分为 :"+part+"批");
for (int i = 0; i < part; i++) {
List<TCAtVoucherRegisterDTO> listPage = list.subList(i*pointsDataLimit, (i+1)*pointsDataLimit);
Task task = new Task(busiTaskService , listPage, this.getClass().getSimpleName());
taskList.add(task);
}
if(size > pointsDataLimit*part) {
List<TCAtVoucherRegisterDTO> listPage = list.subList(pointsDataLimit*part, size);
Task task = new Task(busiTaskService, listPage, this.getClass().getSimpleName());
taskList.add(task);
}
}else{
busiTaskService.batchExecuteBusi(list);
}
}else{
System.out.println("没有数据!!!");
}
try {
if (taskList.size() > 0) {
TaskUtil.getInstance().doFixTask(taskList);
}
}
catch (Exception e) {
throw new CoreException(e.getMessage());
}
logger.info("xxxx 结束:");
}