報表查詢中,可能涉及過多業務,在sql優化以後,仍然存在查詢過慢,導致串行查詢不適用情況,引入Future接口進行多線程查詢,實現快速生成報表;
主線程類:
//利用多線程查詢數據
ThreadPoolExecutor threadPool = ImportDataThreadPoolUtil.getInstance();
//期初數
ReportCallable startPc = new ReportCallable(startSqlQuery);//期初數
FutureTask<List<Object[]>> startFt = new FutureTask<List<Object[]>>(startPc);//期初任務
threadPool.execute(startFt);
//期末數
ReportCallable endPc = new ReportCallable(endSqlQuery);//期末數
FutureTask<List<Object[]>> endFt = new FutureTask<List<Object[]>>(endPc);//期末任務
threadPool.execute(endFt);
//放款數
ReportCallable disbursementPc = new ReportCallable(disbursementSqlQuery);//放款數據
FutureTask<List<Object[]>> disbursementFt = new FutureTask<List<Object[]>>(disbursementPc);//放款數據
threadPool.execute(disbursementFt);
//回收數
ReportCallable receivePc = new ReportCallable(receiveSqlQuery);//回收數據
FutureTask<List<Object[]>> receiveFt = new FutureTask<List<Object[]>>(receivePc);//回收數據
threadPool.execute(receiveFt);
//逾期數
ReportCallable overduePc = new ReportCallable(overdueSqlQuery);//逾期數據
FutureTask<List<Object[]>> overdueFt = new FutureTask<List<Object[]>>(overduePc);//逾期任務
threadPool.execute(overdueFt);
// 日均數
ReportCallable avgAmountPc = new ReportCallable(avgSqlQuery);//日均數據
FutureTask<List<Object[]>> avgAmountFt = new FutureTask<List<Object[]>>(avgAmountPc);//日均任務
threadPool.execute(avgAmountFt);
//逾期剩餘數
ReportCallable overdueLeftPc = new ReportCallable(overdueLeftSqlQuery);//逾期剩餘金額
FutureTask<List<Object[]>> overdueLeftFt = new FutureTask<List<Object[]>>(overdueLeftPc);//日均任務
threadPool.execute(overdueLeftFt);
List<Object[]> startList = null;//期初數
List<Object[]> endList = null;//期末數
List<Object[]> disbursementList = null;//放款數
List<Object[]> receiveList = null;//回收數據
List<Object[]> overdueList = null;//逾期數據
List<Object[]> avgPrincipalAmountList = null;//日均
List<Object[]> overdueLeftList = null;//逾期剩餘
//增加過期時間房/防止死循環
Long userTime = 0l;
while (true && userTime < 1800) {
if (startFt.isDone() && endFt.isDone() && disbursementFt.isDone()
&& receiveFt.isDone() && overdueFt.isDone() && avgAmountFt.isDone()
&& overdueLeftFt.isDone()) {
break;
}
startList = startFt.get();//期初數
endList = endFt.get();//期末數
disbursementList = disbursementFt.get();//放款數據
receiveList = receiveFt.get();//回收哦數據
overdueList = overdueFt.get();//逾期數據
overdueLeftList = overdueLeftFt.get();//逾期剩餘
avgPrincipalAmountList = avgAmountFt.get();//日均
Thread.sleep(1000);//線程鎖定(1s)
userTime++;
}
接口實現:
public class ReportCallable implements Callable<List<Object[]>> {
private SQLQuery sqlQuery;
public ReportCallable(SQLQuery sqlQuery) {
this.sqlQuery = sqlQuery;
}
public List<Object[]> call() throws Exception {
return (List<Object[]>)sqlQuery.list();
}
}