先直接上代碼如下:
一、需要實現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());
}
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。