java多執行緒設定 執行緒超時 非阻塞實現
執行緒是屬於非同步計算模型,所以你不可能直接從別的執行緒中得到函式返回值。
這時候,Future就出場了。Futrue可以監視目標執行緒呼叫call的情況,當你呼叫Future的get()方法以獲得結果時,當前執行緒就開始阻塞,直接call方法結束返回結果。
我目前的需求僅是執行緒超時 拋棄任務
設定超時方法
Future<?> future = executor.submit(c);
try {
future.get(timeout, timeUnit);//阻塞 timeout超時時間 timeUnit設定單位
return true;
} catch (TimeoutException e) {
future.cancel(true);//設定true 超時會終止這個任務,false會把任務跑完
logger.info("任務執行超時,強制退出 ! 任務執行失敗sum: " + getErrorCount() + " this協議:" + message.getCmd() + " 超過:" + timeout+ " 毫秒 ");
return false;
}
CompletableFuture類實現了CompletionStage和Future介面。Future是Java 5新增的類,用來描述一個非同步計算的結果,但是獲取一個結果時方法較少,要麼通過輪詢isDone,確認完成後,呼叫get()獲取值,要麼呼叫get()設定一個超時時間。但是這個get()方法會阻塞住呼叫執行緒,這種阻塞的方式顯然和我們的非同步程式設計的初衷相違背。
為了解決這個問題,JDK吸收了guava的設計思想,加入了Future的諸多擴充套件功能形成了CompletableFuture。
CompletableFuture.supplyAsync 允許你基於ForkJoinPool 非同步地執行一個任務,同時也有選項供你選擇更多對執行緒池的控制
可以指定執行緒池
static CompletableFuture runAsync(Runnable runnable);
static CompletableFuture runAsync(Runnable runnable, Executor executor);//指定執行緒池
static CompletableFuture supplyAsync(Supplier supplier);
static CompletableFuture supplyAsync(Supplier supplier, Executor executor);//指定執行緒池
解決方案2 用jdk1.8 CompletableFuture.supplyAsync 方法 實現非阻塞
supplyAsync是非同步提交任務(其實我感覺跟用執行緒提交類似)
*************************Future執行緒超時設定 對查詢資料類操作 無法停止當前執行緒******************************
//返回值為boolean
CompletableFuture.supplyAsync(() -> {
Future<?> future = executor.submit(c);
try {
future.get(timeout, timeUnit);//阻塞 timeout超時時間 timeUnit設定單位
return true;
} catch (TimeoutException e) {
future.cancel(true);//設定true 超時會終止這個任務,false會把任務跑完
logger.info("任務執行超時,強制退出 ! 任務執行失敗sum: " + getErrorCount() + " this協議:" + message.getCmd() + " 超過:" + timeout+ " 毫秒 ");
return false;
}
return true;
});
CompletableFuture.supplyAsync 方法Demo演示
import java.util.concurrent.CompletableFuture;
public class Test {
public Test() {
// TODO Auto-generated constructor stub
}
public static void main(String[] s) {
System.err.println("Start");
// 返回值為boolean
CompletableFuture.supplyAsync(() -> {
try {
//阻塞10秒
Thread.sleep(10 * 1000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
});
System.err.println("end");
}
}