先直接上代码如下:
一、需要实现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());
}
}