java中Future使用方法舉例詳細介紹
一、什么是Future?
在并發(fā)編程中,可以通過Future對象來異步獲取結果。
使用Thread或runnable接口都不能獲取異步的執(zhí)行結果,因為他們沒有返回值。而通過實現(xiàn)Callable接口和Future就可以獲取異步執(zhí)行的結果,當異步執(zhí)行結束后,返回結果將保存在Future中。使用Future就可以讓我們暫時去處理其他的任務而無需一直等待結果,等異步任務執(zhí)行完畢再返回其結果。
二、Future中的get方法
1、get方法
獲取任務結束后返回的結果,如果調(diào)用時,任務還沒有結束,則會進行阻塞線程,直到任務完成。該阻塞是可以被打斷的,打斷的線程是調(diào)用get方法的線程,被打斷后原任務會依舊繼續(xù)執(zhí)行。
V get() throws InterruptedException, ExecutionException;
2、指定時間的get方法
獲取任務結束后返回的結果,如果調(diào)用時,任務還沒有結束,則會進行阻塞線程,等待一定時間,如果在規(guī)定時間內(nèi)任務結束則返回結果,否則拋出TimeoutException,超時后任務依舊會繼續(xù)執(zhí)行。該阻塞是可以被打斷的,打斷的線程是調(diào)用get方法的線程,被打斷后原任務會依舊繼續(xù)執(zhí)行。
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
三、Future代碼示例
步驟1:創(chuàng)建一個線程池
public class AsyncTaskExecutor { /** * 核心線程數(shù) */ private static final int corePoolSize = 10; /** * 最大線程數(shù) */ private static final int maxPoolSize = 30; /** * 空閑線程回收時間 * 空閑線程是指:當前線程池中超過了核心線程數(shù)之后,多余的空閑線程的數(shù)量 */ private static final int keepAliveTime = 100; /** * 任務隊列/阻塞隊列 */ private static final int blockingQueueSize = 99999; private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor( corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(blockingQueueSize), new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(), new ThreadPoolExecutor.CallerRunsPolicy() ); /** * 異步任務執(zhí)行 * * @param task */ public static void execute(Runnable task) { executorPool.execute(task); } /** * 異步執(zhí)行任務Callable, 通過Future獲取結果 * * @param task * @param <T> * @return */ public static <T> Future<T> submit(Callable<T> task) { return executorPool.submit(task); } /** * 異步執(zhí)行任務Runnable,通過Future獲取結果 * * @param task * @return */ public static Future<?> submit(Runnable task) { return executorPool.submit(task); } }
步驟2:編寫測試類
@Test public void test2() { try { Future<String> future = AsyncTaskExecutor.submit(() -> { log.info("[Future Task] future task start..."); try { //模擬任務執(zhí)行 Thread.sleep(5000); } catch (InterruptedException e) { log.info(e.getMessage()); } log.info("[Future Task] future task end..."); return "Task completed..."; }); //執(zhí)行其他任務 log.info("[Main Thread] main thread is running..."); //使用future阻塞等待任務完成,并獲取結果 String futureResult = future.get(); log.info("[Main Thread] {}", futureResult); }catch (Exception e) { e.printStackTrace(); } }
步驟3:查看結果
2024-05-28 10:58:23.633 INFO 1184 --- [ main] com.example.demo.dao.UserDaoTest : [Main Thread] main thread is running... 2024-05-28 10:58:23.633 INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest : [Future Task] future task start... 2024-05-28 10:58:28.633 INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest : [Future Task] future task end... 2024-05-28 10:58:28.634 INFO 1184 --- [ main] com.example.demo.dao.UserDaoTest : [Main Thread] Task completed...
四、ListenableFuture
public class AsyncTaskExecutor { /** * 核心線程數(shù) */ private static final int corePoolSize = 10; /** * 最大線程數(shù) */ private static final int maxPoolSize = 30; /** * 空閑線程回收時間 * 空閑線程是指:當前線程池中超過了核心線程數(shù)之后,多余的空閑線程的數(shù)量 */ private static final int keepAliveTime = 100; /** * 任務隊列/阻塞隊列 */ private static final int blockingQueueSize = 99999; private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor( corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(blockingQueueSize), new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(), new ThreadPoolExecutor.CallerRunsPolicy() ); /** * 創(chuàng)建一個ListeningExecutorService,用于執(zhí)行異步任務 * (通過submit提交任務,以ListenableFuture獲取結果) */ private static final ListeningExecutorService LISTENING_EXECUTOR = MoreExecutors.listeningDecorator(executorPool); /** * 異步任務執(zhí)行 * * @param task */ public static void execute(Runnable task) { executorPool.execute(task); } /** * 異步執(zhí)行任務Callable, 通過ListenableFuture獲取結果 * * @param task * @param <T> * @return */ public static <T> ListenableFuture<T> submit(Callable<T> task) { return LISTENING_EXECUTOR.submit(task); } /** * 異步執(zhí)行任務Runnable,通過Future獲取結果 * * @param task * @return */ public static ListenableFuture<?> submit(Runnable task) { return LISTENING_EXECUTOR.submit(task); } }
//示例1: @Test public void test2() { ListenableFuture<School> listenableFuture1 = AsyncTaskExecutor.submit(() -> { try { //模擬任務執(zhí)行 Thread.sleep(2000); } catch (InterruptedException e) { log.info(e.getMessage()); } return new School("DSchool"); }); ListenableFuture<School> listenableFuture2 = AsyncTaskExecutor.submit(() -> { try { //模擬任務執(zhí)行 Thread.sleep(3000); } catch (InterruptedException e) { log.info(e.getMessage()); } return new School("ESchool"); }); //阻塞等待,直到listenableFuture1 和 listenableFuture2都獲取到結果后或其中一個異常 Futures.successfulAsList(listenableFuture1, listenableFuture2).get(); School resSchool1 = listenableFuture1.get(); School resSchool2 = listenableFuture2.get(); log.info("[Main Thread] result1 is {}", JSON.toJSONString(resSchool1)); log.info("[Main Thread] result2 is {}", JSON.toJSONString(resSchool2)); //任意位置即時設定ListenableFuture的返回結果 ListenableFuture<School> listenableFuture3 = Futures.immediateFuture(new School("aaa")); ListenableFuture<School> listenableFuture4 = Futures.immediateFailedFuture(new Exception("eeee")); log.info("[Main Thread] listenableFuture3 is {}", listenableFuture3.get()); log.info("[Main Thread] listenableFuture4 is {}", listenableFuture4.get()); }catch (Exception e) { e.printStackTrace(); } } //示例2: public static void main(String[] args) { // 創(chuàng)建一個ListeningExecutorService,用于執(zhí)行異步任務 ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); // 提交一個異步任務,并得到ListenableFuture對象 ListenableFuture<String> listenableFuture = executor.submit(() -> { // 模擬耗時操作 Thread.sleep(2000); return "Result of the asynchronous computation"; }); // 注冊異步操作完成時的回調(diào)函數(shù) Futures.addCallback(listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(String result) { System.out.println("Result: " + result); executor.shutdown(); // 關閉executor } @Override public void onFailure(Throwable t) { t.printStackTrace(); executor.shutdown(); // 關閉executor } }, executor); }
五、CompletableFuture
//示例1: public static void main(String[] args) { // 創(chuàng)建一個CompletableFuture對象 CompletableFuture<School> completableFuture = new CompletableFuture<>(); // 異步任務:模擬一個耗時操作 new Thread(() -> { try { // 模擬耗時操作 Thread.sleep(2000); // 完成CompletableFuture并設置值 completableFuture.complete(new School("completableSchool")); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // 在這里等待異步任務的結果并輸出 try { School result = completableFuture.get(); log.info("[CompletableFuture] result is {}" ,result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } //示例2: @Test public void test2() { try { //創(chuàng)建一個CompletableFuture對象 CompletableFuture<School> schoolFuture = new CompletableFuture<>(); //任意位置即時設定CompletableFuture的返回結果 schoolFuture.complete(new School("FSchool")); School school = schoolFuture.get(); log.info("[Main Thread] result is {}", JSON.toJSONString(school)); }catch (Exception e) { log.info(e.getMessage()); } }
六、SettableFuture
//示例1: public static void main(String[] args) { // 創(chuàng)建一個SettableFuture對象 SettableFuture<String> settableFuture = SettableFuture.create(); // 手動設置異步操作的結果 settableFuture.set("Result of the asynchronous computation"); // 注冊異步操作完成時的回調(diào)函數(shù) settableFuture.addListener(() -> { try { String result = settableFuture.get(); // 獲取異步操作的結果 System.out.println("Result: " + result); } catch (Exception e) { e.printStackTrace(); } }, Runnable::run); } //示例2: @Test public void test2() { try { //創(chuàng)建一個SettableFuture對象 SettableFuture<School> settableFuture = SettableFuture.create(); //任意位置即時設定SettableFuture的返回結果 settableFuture.set(new School("GSchool")); School setSchool = settableFuture.get(); log.info("[Main Thread] setSchool is {}", JSON.toJSONString(setSchool)); }catch (Exception e) { log.info(e.getMessage()); } }
總結
到此這篇關于java中Future使用方法的文章就介紹到這了,更多相關java中Future使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中system.exit(0) 和 system.exit(1)區(qū)別
本文主要介紹了Java中system.exit(0) 和 system.exit(1)區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05SpringBoot中@ConfigurationProperties注解實現(xiàn)配置綁定的三種方法
這篇文章主要介紹了SpringBoot中@ConfigurationProperties注解實現(xiàn)配置綁定的三種方法,文章內(nèi)容介紹詳細需要的小伙伴可以參考一下2022-04-04IDEA 2020.1 搜索不到Chinese (Simplified) Language
小編在安裝中文插件時遇到IDEA 2020.1 搜索不到Chinese ​(Simplified)​ Language Pack EAP,無法安裝的問題,本文給大家分享我的解決方法,感興趣的朋友一起看看吧2020-04-04