1. 程式人生 > >非同步處理獲取結果集非同步介面Future

非同步處理獲取結果集非同步介面Future

Future介面是Concurrent包下的,關於他的解釋,原始碼給的解釋是


package java.util.concurrent;

/**
 * A {@code Future} represents the result of an asynchronous
 * computation.  Methods are provided to check if the computation is
 * complete, to wait for its completion, and to retrieve the result of
 * the computation.  The result can only be retrieved using method
 * {@code get} when the computation has completed, blocking if
 * necessary until it is ready.  Cancellation is performed by the
 * {@code cancel} method.  Additional methods are provided to
 * determine if the task completed normally or was cancelled. Once a
 * computation has completed, the computation cannot be cancelled.
 * If you would like to use a {@code Future} for the sake
 * of cancellability but not provide a usable result, you can
 * declare types of the form {@code Future<?>} and
 * return {@code null} as a result of the underlying task.

雖然我也不怎麼明白

在springboot的使用中,我在

log.debug("伴隨資料獲取完畢,開始等待伴隨站點獲取... ...");
        List<Future<String>> futureList1 = new ArrayList<>();
        if (flag){
            for (FollowIMSI followIMSI:newList){
                String fieldStr = StringUtils.join(fields, ",");
                String sql = SqlUtils.getTargetSql(fieldStr,esIndex,followType,followIMSI.getFollowCode(),startTime,endTime);
                log.debug("開始伴隨站點獲取:"+sql);
                Future<String>  followIMSIFuture = followServiceByAsync.findFollowSiteByGP(sql,followIMSI);
                futureList1.add(followIMSIFuture);
            }
        }
        log.debug("等待標籤資料全部獲取處理完成... ...");
        for (Future<String> f :futureList1){
            String s = f.get();
        }
        log.debug("伴隨站點獲取完畢,開始獲取標籤資料... ...");

在方法findFollowSiteByGP(sql,followIMSI)中,我只是返回一個new AsyncResult<>("");一個空的字串,就是證明執行完成了....

而在下面對收集了Future結果集的list進行遍歷查詢,如果能get()到值的話,就說明已經非同步已經執行完成,整個for結束,也是所有所有非同步都執行完成了....所以認為結果是沒有問題的.

但是在後面的處理的時候,發現數據量是有不一致,且時常會卡頓..

後來我經理給改了點東西;

如下:

     for (Future<String> f :futureList1){
            //String s = f.get();
            try{
                while (true){
                    if(f.isDone() && !f.isCancelled()){
                        log.debug("查詢執行緒處理完成... ...");
                        break;
                    }else{
                        Thread.sleep(100);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

就是在遍歷結果集list的時候,不使用get()方法,而是使用Futurn的isDone()方法和isCanceld()方法來判斷執行緒是否是執行結束..

然後在網上找了點資料,講到Future介面的get()的方法,

這樣的設計一般都約定,當使用 get() 阻塞式訪問時,返回後那個任務已經完成了 (不管結果是 isDone() 還是 isCancelled())。

而我們對已經取消的執行緒程序是不需要的,

所以後面的for迴圈中是對isDone()&&!isCancled()進行的跳出.

但是Thread.sleep(100);也有點兒硬性條件要求了...所以,有點兒線索,但不是太懂的那種...

望大佬們批評指正.!!!