submit 和 excute是有啥區別
如果有這樣的需求:
多線程實現下載,提高效率。
不論是Thread類還是Runnable接口重寫run方法,有個特點就是沒有返回值~~~~~~
我都主線程 如何知道子線程程序執行完畢呢? 子線程執行完畢 立馬告訴主線程 可以wait 和 notify
在Java中,創建線程一般有兩種方式,一種是繼承Thread類,一種是實現Runnable接口。然而,這兩種方式的缺點是在線程任務執行結束后,無法獲取執行結果。我們一般只能采用共享變量或共享存儲區以及線程通信的方式實現獲得任務結果的目的。
不過,Java中,也提供了使用Callable和Future來實現獲取任務結果的操作。Callable用來執行任務,產生結果,而Future用來獲得結果。
可以看到,與Runnable接口不同之處在於,call方法帶有泛型返回值V。
submit返回 Future類型
package com.toov5.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CallableThreadTest { public static void main(String[] args) throws InterruptedException,ExecutionException { ExecutorService executorService=Executors.newCachedThreadPool(); //提交時候 線程池開始執行 System.out.println("1主線程開始執行"); Future<String> sFuture = executorService.submit(new TaskCallable()); System.out.println("hhhhh"); String ResultStirng = sFuture.get(); //下面線程執行的結果 System.out.println("2結果:"+ResultStirng); System.out.println("okokokok"); } } class TaskCallable implements Callable<String>{ //可以返回線程結果 @Override public String call() throws Exception { System.out.println("3正在執行任務,請等待五秒"); Thread.sleep(5000); System.out.println("4執行完畢"); return "這是返回結果"; } }
1和2是不需要阻塞的 后面的需要阻塞哈
子線程去執行 主線程愛干滿干嘛不用專門去等待 子線程運行完畢 主獲取結果
Future常用方法
V get() :獲取異步執行的結果,如果沒有結果可用,此方法會阻塞直到異步計算完成。
V get(Long timeout , TimeUnit unit) :獲取異步執行結果,如果沒有結果可用,此方法會阻塞,但是會有時間限制,如果阻塞時間超過設定的timeout時間,該方法將拋出異常。
boolean isDone() :如果任務執行結束,無論是正常結束或是中途取消還是發生異常,都返回true。future.isDone()
boolean isCanceller() :如果任務完成前被取消,則返回true。 future.isCanceller()
boolean cancel(boolean mayInterruptRunning) :如果任務還沒開始,執行cancel(...)方法將返回false;如果任務已經啟動,執行cancel(true)方法將以中斷執行此任務線程的方式來試圖停止任務,如果停止成功,返回true;當任務已經啟動,執行cancel(false)方法將不會對正在執行的任務線程產生影響(讓線程正常執行到完成),此時返回false;當任務已經完成,執行cancel(...)方法將返回false。mayInterruptRunning參數表示是否中斷執行中的線程。
通過方法分析我們也知道實際上Future提供了3種功能:
(1)能夠中斷執行中的任務
(2)判斷任務是否執行完成
(3)獲取任務執行完成后額結果。
Future模式
Future模式的核心在於:去除了主函數的等待時間,並使得原本需要等待的時間段可以用於處理其他業務邏輯
Futrure模式:對於多線程,如果線程A要等待線程B的結果,那么線程A沒必要等待B,直到B有結果,可以先拿到一個未來的Future,等B有結果是再取真實的結果。
在多線程中經常舉的一個例子就是:網絡圖片的下載,剛開始是通過模糊的圖片來代替最后的圖片,等下載圖片的線程下載完圖片后在替換。而在這個過程中可以做一些其他的事情。
首先客戶端向服務器請求RealSubject,但是這個資源的創建是非常耗時的,怎么辦呢?這種情況下,首先返回Client一個FutureSubject,以滿足客戶端的需求,於此同時呢,Future會通過另外一個Thread 去構造一個真正的資源,資源准備完畢之后,在給future一個通知。如果客戶端急於獲取這個真正的資源,那么就會阻塞客戶端的其他所有線程,等待資源准備完畢。