java面試常問的Runnable和Callable的區(qū)別
Runnable
Runnable接口非常簡單,就定義了一個方法run(), 實現(xiàn)Runnable接口的run方法就可以實現(xiàn)多線程
// 函數(shù)式接口 @FunctionalInterface public interface Runnable { public abstract void run(); }
Callable
可能很多人都知道要想在多線程中獲取異步返回值結(jié)果一般是用Callable和FutureTask接口來實現(xiàn),但可能很多人都不知道其實Callable是依賴于Runnable的run方法進行執(zhí)行任務的,然后在通過FutureTask來收集返回值結(jié)果,下面咱們就自己模擬寫一份FutureTask代碼來看看是怎么實現(xiàn)的吧。
/** * @author yinfeng * @description 自己實現(xiàn)futureTask,基于park/unpark進行線程通訊 * @since 2022/1/9 21:32 */ public class MyFutureTask<T> implements Runnable { Callable<T> callable; /** * callable執(zhí)行結(jié)果 */ T result; /** * task執(zhí)行狀態(tài) */ String state = "new"; /** * 存儲正在等待的消費者 */ LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(); public MyFutureTask(Callable<T> callable) { this.callable = callable; } @Override public void run() { try { result = callable.call(); } catch (Exception e) { e.printStackTrace(); } finally { state = "end"; } // 任務執(zhí)行完成后通過unpark通知消費者 System.out.println(Thread.currentThread().getName() + " 生產(chǎn)者執(zhí)行結(jié)束,通知消費者"); while (true) { Thread waiter = waiters.poll(); if (waiter == null) { break; } LockSupport.unpark(waiter); } } /** * park / unpark */ public T get() throws Exception { Thread mainThread = Thread.currentThread(); // 塞入等待的集合中 waiters.add(mainThread); // 判斷狀態(tài) System.out.println(Thread.currentThread().getName() + " 消費者進入等待"); while (!"end".equals(state)) { // 阻塞等待任務執(zhí)行完成后通知 LockSupport.park(mainThread); } return result; } }
我們寫個demo測試一下
/** * @author yinfeng * @description * @since 2022/1/9 21:32 */ public class FutureTaskTest { public static void main(String[] args) throws Exception { final MyFutureTask<String> futureTask = new MyFutureTask<>(() -> { Thread.sleep(5000); return "任務完成888"; }); new Thread(futureTask).start(); final String result = futureTask.get(); System.out.println("結(jié)果:"+result); // 控制臺打印如下: // main 消費者進入等待 // Thread-0 生產(chǎn)者執(zhí)行結(jié)束,通知消費者 // 結(jié)果:任務完成888 } }
可以看到我們的demo也是正常運行的,所以很關鍵的一點還是Callable是依賴于Runnable的run方法進行執(zhí)行任務的
到此這篇關于java面試常問的Runnable和Callable的區(qū)別的文章就介紹到這了,更多相關java Runnable和Callable區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Java使用多線程批次查詢大量數(shù)據(jù)(Callable返回數(shù)據(jù))方式
- Java通過Callable實現(xiàn)多線程
- Java多線程中Callable和Future的解讀
- Java中的Callable實現(xiàn)多線程詳解
- Java使用Callable接口實現(xiàn)多線程的實例代碼
- Java多線程實現(xiàn)之Callable詳解
- Java中Runnable和Callable分別什么時候使用
- Java中Runnable與Callable接口的區(qū)別詳解
- 詳解Java中Callable和Future的區(qū)別
- Java使用Runnable和Callable實現(xiàn)多線程的區(qū)別詳解
- Java并發(fā)教程之Callable和Future接口詳解
- Java中callable的實現(xiàn)原理
相關文章
SpringBoot Knife4j在線API文檔框架基本使用
knife4j是為Java MVC框架集成Swagger生成Api文檔的增強解決方案,這篇文章主要介紹了SpringBoot中使用Knife4J在線API文檔框架,需要的朋友可以參考下2022-12-12springboot集成opencv實現(xiàn)人臉識別功能的詳細步驟
大家都知道OpenCV是一個基于BSD許可(開源)發(fā)行的跨平臺計算機視覺和機器學習軟件庫,可以運行在Linux、Windows、Android和Mac OS操作系統(tǒng)上今天通過本文給大家分享springboot集成opencv實現(xiàn)人臉識別,感興趣的朋友一起看看吧2021-06-06Plugin ‘org.springframework.boot:spring-boot-maven-plug
這篇文章給大家介紹了Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found的解決方案,親測可用,文中給出了兩種解決方法,需要的朋友可以參考下2024-01-01全面匯總SpringBoot和SpringClould常用注解
Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能,這篇文章就帶你來了解一下2021-08-08使用maven-archetype-plugin現(xiàn)有項目生成腳手架的方法
這篇文章主要介紹了使用maven-archetype-plugin現(xiàn)有項目生成腳手架的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11