java用多線程批次查詢(Callable返回數據)方式

多線程有好幾種方式,今天說的方式比較好,實現Callable<> 這種方式能返回查詢的數據,加上Future異步獲取方式,查詢效率大大加快

package com.ThreadPoolHadel;
 
import com.sqlSource.SqlHadle;
 
import java.util.List;
import java.util.concurrent.Callable;
 
/**
 * Created by df on 2018/9/20.
 */
public class ThredQuery implements Callable<List> {
 
 
    SqlHadle sqlHadle=new SqlHadle();
 
    private String search;//查詢條件 根據條件來定義該類的屬性
 
    private int bindex;//當前頁數
 
    private int num;//每頁查詢多少條
 
    private String table;//要查詢的表名,也可以寫死,也可以從前面傳
 
    private List page;//每次分頁查出來的數據
 
    public  ThredQuery(int bindex,int num,String table) {
        this.bindex=bindex;
        this.num=num;
        this.table=table;
        //分頁查詢數據庫數據
        page=sqlHadle.queryTest11(bindex,num,table);
    }
 
    @Override
    public List call() throws Exception {
        //返回數據給Future
        return page;
    }
}

調用類:

package com.service;
 
 
import com.ThreadPoolHadel.ThredQuery;
import com.sqlSource.SqlHadle;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
 
import java.util.List;
import java.util.concurrent.*;
 
/**
 * Created by df on 2018/9/20.
 */
 
@Service
public class TheardQueryService {
 
    SqlHadle sqlHadle=new SqlHadle();
 
    public List<List> getMaxResult(String table) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();//開始時間
        List<List> result = new ArrayList<>();//返回結果
        //查詢數據庫總數量
        int count = sqlHadle.count(table);
        int num = 8000;//一次查詢多少條
        //需要查詢的次數
        int times = count / num;
        if (count % num != 0) {
            times = times + 1;
        }
        //開始頁數  連接的是orcle的數據庫  封裝的分頁方式  我的是從1開始
        int bindex = 1;
        //Callable用於產生結果
        List<Callable<List>> tasks = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            Callable<List> qfe = new ThredQuery(bindex, num, table);
            tasks.add(qfe);
            bindex += bindex;
        }
        //定義固定長度的線程池  防止線程過多
        ExecutorService executorService = Executors.newFixedThreadPool(15);
        //Future用於獲取結果
        List<Future<List>> futures=executorService.invokeAll(tasks);
        //處理線程返回結果
        if(futures!=null&&futures.size()>0){
            for (Future<List> future:futures){
             result.addAll(future.get());
            }
        }
 
        executorService.shutdown();//關閉線程池
        long end = System.currentTimeMillis();
        System.out.println("線程查詢數據用時:"+(end-start)+"ms");
        return result;
    }
 
 
}

9600多條數據3秒內查詢完,對於之前10m查詢完畢,已經提高很多的效率了

80000多條數據7m就完成了

830305萬的數據需要40m ,哈哈哈,也算差不多一百萬的數據了,最主要的是沒有卡死,好像不經過處理很容易卡死

 

5184121萬的數據報GC了,那就演示到這吧,五百萬的數據實在不適合這樣查

最主要的是,你的數據量大的話要相應的更改調用方法裏的 num,一次性多查點,效率會高很多
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章