处理批量任务 :
本文
转载地址 : http://blog.csdn.net/u010963948/article/details/54669708
先直接上代码如下:
一、需要实现Callable接口(可以使用泛型)
- package com.innotek.spms.service.finance;
- import com.innotek.common.util.SpringContextUtil;
- import com.innotek.spms.entity.busi.Collector;
- import com.innotek.spms.entity.busi.Payment;
- import com.innotek.spms.entity.fanc.PaymentCard;
- import com.innotek.spms.entity.swap.OwefeeRecord;
- import com.innotek.spms.entity.swap.RepayRecord;
- import com.innotek.spms.entity.tran.PayOrder;
- import com.innotek.spms.service.PayBackService;
- import org.springframework.beans.factory.annotation.Autowired;
- import java.util.concurrent.Callable;
- public class RepayTask implements Callable<Long> {
- private PayOrder payOrder;
- private Collector collector;
- private Payment payment;
- private String payAccount;
- private String cityCode;
- private OwefeeRecord owefeeRecord;
- private RepayRecord tempEntity;
- private long oweFee;
- private long paymentId;
- private PaymentCard card;
- public RepayTask(PayOrder payOrder, Collector collector, Payment payment,
- String payAccount, String cityCode, OwefeeRecord owefeeRecord, RepayRecord tempEntity,
- long oweFee, long paymentId, PaymentCard card) {
- this.payOrder=payOrder;
- this.collector=collector;
- this.payment=payment;
- this.payAccount=payAccount;
- this.cityCode=cityCode;
- this.owefeeRecord=owefeeRecord;
- this.tempEntity=tempEntity;
- this.oweFee=oweFee;
- this.paymentId=paymentId;
- this.card=card;
- }
- @Override
- public Long call() throws Exception {
- PayBackService payBackService=(PayBackService) SpringContextUtil.getBean("payBackService");
- return payBackService.eliminateRecordImpl(payOrder, collector, payment,
- payAccount, cityCode, owefeeRecord, tempEntity, oweFee,
- paymentId, card);
- }
- }
二、创建线程池使用:
- // 线程执行补缴接口
- ExecutorService executor= Executors.newCachedThreadPool();
- List<RepayTask> taskList=new ArrayList<RepayTask>();
- RepayTask task=new RepayTask(payOrder, collector, payment,
- payAccount, cityCode, owefeeRecord, tempEntity, oweFee,
- paymentIdFianl, card);
- taskList.add(task);
- List<Future<Long>>resultList=null;
- try {
- //执行全部的线程
- resultList=executor.invokeAll(taskList);
- if(CollectionUtils.isNotEmpty(resultList)){
- for (int i=0; i<resultList.size(); i++){
- Future<Long> future=resultList.get(i);
- sum+= future.get();
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
三、其他详解如下:
并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果。
所以run的返回值是void类型。
如果是一个多线程协作程序,比如菲波拉切数列,1,1,2,3,5,8...使用多线程来计算。
但后者需要前者的结果,就需要用callable接口了。
callable用法和runnable一样,只不过调用的是call方法,该方法有一个泛型返回值类型,你可以任意指定。
线程是属于异步计算模型,所以你不可能直接从别的线程中得到函数返回值。
这时候,Future就出场了。Futrue可以监视目标线程调用call的情况,当你调用Future的get()方法以获得结果时,当前线程就开始阻塞,直接call方法结束返回结果。
下面三段简单的代码可以很简明的揭示这个意思:
runnable接口实现的没有返回值的并发编程。
callable实现的存在返回值的并发编程。(call的返回值String受泛型的影响)
同样是callable,使用Future获取返回值。
package demo.future;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 试验 Java 的 Future 用法
*/
public class FutureTest {
public static class Task implements Callable<String> {
@Override
public String call() throws Exception {
String tid = String.valueOf(Thread.currentThread().getId());
System.out.printf("Thread#%s : in call\n", tid);
return tid;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
List<Future<String>> results = new ArrayList<Future<String>>();
ExecutorService es = Executors.newCachedThreadPool();
for(int i=0; i<100;i++)
results.add(es.submit(new Task()));
for(Future<String> res : results)
System.out.println(res.get());
}
}