Java中的FutureTask實(shí)現(xiàn)代碼實(shí)例
FutureTask實(shí)現(xiàn)
FutureTask是Future的實(shí)現(xiàn),用來(lái)異步任務(wù)的獲取結(jié)果,可以啟動(dòng)和取消異步任務(wù),查詢異步任務(wù)是否計(jì)算結(jié)束以及獲取最終的異步任務(wù)的結(jié)果。
通過(guò)get()方法來(lái)獲取異步任務(wù)的結(jié)果,但是會(huì)阻塞當(dāng)前線程直至異步任務(wù)執(zhí)行結(jié)束。
一旦任務(wù)執(zhí)行結(jié)束,任務(wù)不能重新啟動(dòng)或取消,除非調(diào)用runAndReset()方法
代碼示例:
public class ThreadTest_Demo { static ExecutorService executors = Executors.newScheduledThreadPool(2); public ThreadTest_Demo() { } public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<String> callable = new Callable<String>() { public String call() throws Exception { String str = "返回某個(gè)數(shù)據(jù)!"; return str; } }; Future<String> submit = executors.submit(callable); KaneFutureTask<String> futureTask = new KaneFutureTask(callable); (new Thread(futureTask)).start(); System.out.println((String)futureTask.get()); } }
實(shí)現(xiàn)一個(gè)自己的FutureTask
根據(jù)FutureTask核心原理,要實(shí)現(xiàn)一個(gè)FutureTask必須滿足以下方面:
- 需要泛型定義用以返回結(jié)果類型
- 需要一個(gè)callable對(duì)象,在構(gòu)造方法中傳入
- 需要實(shí)現(xiàn)runnable接口,在run方法中實(shí)現(xiàn)具體結(jié)果計(jì)算
- 需要一個(gè)公開(kāi)的get方法來(lái)獲取結(jié)果
- 如果線程沒(méi)有執(zhí)行完,則調(diào)用get方法的線程需要進(jìn)入等待隊(duì)列
- 需要一個(gè)字段記錄線程執(zhí)行的狀態(tài)
- 需要一個(gè)等待隊(duì)列存儲(chǔ)等待結(jié)果的線程
代碼示例:
public class KaneFutureTask<T> implements Runnable { private Callable<T> callable; T result;//返回的結(jié)果 volatile String state = "NEW";//線程執(zhí)行的狀態(tài) LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue();//存儲(chǔ)等待結(jié)果的線程 public KaneFutureTask(Callable<T> callable) { this.callable = callable; } //run()方法未執(zhí)行未必,阻塞 public T get() { if ("END".equals(this.state)) { return this.result; } else { while(!"END".equals(this.state)) {//這里開(kāi)始阻塞 //把線程存放到容器中 this.waiters.offer(Thread.currentThread()); //阻塞 LockSupport.park(); } return this.result; } } public void run() { try { //執(zhí)行Callable的call方法 this.result = this.callable.call(); } catch (Exception var5) { var5.printStackTrace(); } finally { //線程狀態(tài)修改 this.state = "END"; } //從容器中取出當(dāng)前線程 Thread waiter = (Thread)this.waiters.poll(); for(waiter != null) { //取消阻塞 LockSupport.unpark(waiter); waiter = (Thread)this.waiters.poll() } } }
到此這篇關(guān)于Java中的FutureTask手寫代碼實(shí)例的文章就介紹到這了,更多相關(guān)FutureTask代碼實(shí)例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot 編程式事務(wù)使用及兩種實(shí)現(xiàn)方式
編程式事務(wù)管理是通過(guò)編寫代碼來(lái)管理事務(wù),相對(duì)于聲明式事務(wù)(@Transactional注解),它提供了更細(xì)粒度的事務(wù)控制,這篇文章主要介紹了SpringBoot 編程式事務(wù)使用及兩種實(shí)現(xiàn)方式,需要的朋友可以參考下2024-12-12SpringBoot整合mybatis-generator-maven-plugin的方法
這篇文章主要介紹了SpringBoot整合mybatis-generator-maven-plugin,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11Java實(shí)現(xiàn)簡(jiǎn)易的洗牌和發(fā)牌功能
本文主要介紹了Java實(shí)現(xiàn)簡(jiǎn)易的洗牌和發(fā)牌功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04Java基礎(chǔ)之詳細(xì)總結(jié)五種常用運(yùn)算符
在通常代碼邏輯處理中,我們常常都會(huì)使用到運(yùn)算符,今天我們就詳細(xì)了解一下運(yùn)算符的使用以及分類.運(yùn)算符是對(duì)常量或者變量進(jìn)行操作的符號(hào),它分為算術(shù)運(yùn)算符,賦值運(yùn)算符,比較運(yùn)算符,邏輯運(yùn)算符以及位運(yùn)算符.需要的朋友可以參考下2021-05-05