Callable
在Java中,創建線程一般有兩種方式,一種是繼承Thread類,一種是實現Runnable接口。然而,這兩種方式的缺點是在線程任務執行結束后,無法獲取執行結果。我們一般只能采用共享變量或共享存儲區以及線程通信的方式實現獲得任務結果的目的。
不過,Java中,也提供了使用Callable和Future來實現獲取任務結果的操作。Callable用來執行任務,產生結果,而Future用來獲得結果。
Callable接口的定義如下:
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
與Runnable接口不同之處在於,call方法帶有泛型返回值V。
Future模式
Future模式的核心在於:去除了主函數的等待時間,並使得原本需要等待的時間段可以用於處理其他業務邏輯
Futrure模式:對於多線程,如果線程A要等待線程B的結果,那么線程A沒必要等待B,直到B有結果,可以先拿到一個未來的Future,等B有結果是再取真實的結果。
在多線程中經常舉的一個例子就是:網絡圖片的下載,剛開始是通過模糊的圖片來代替最后的圖片,等下載圖片的線程下載完圖片后在替換。而在這個過程中可以做一些其他的事情。
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;
/**
* @author wn:
* @version 上午16:53:57
* 類說明
*/
public class ThreadCallTest {
public static void main(String[]args){
ExecutorService executor=Executors.newCachedThreadPool();
Task task=new Task();
Future<Integer> result=executor.submit(task);
if (executor != null)
executor.shutdown();
try {
System.out.println("call result"+result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("over");
}
}
class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("3.開始 ....");
Thread.sleep(3000);
System.out.println("4.結束 ....");
return "xyz";
}
}
當Task啟動后不影響主線程運行,result.get()會等待3秒后返回結果xyz
Future常用方法
V get() :獲取異步執行的結果,如果沒有結果可用,此方法會阻塞直到異步計算完成。
V get(Long timeout , TimeUnit unit) :獲取異步執行結果,如果沒有結果可用,此方法會阻塞,但是會有時間限制,如果阻塞時間超過設定的timeout時間,該方法將拋出異常。
boolean isDone() :如果任務執行結束,無論是正常結束或是中途取消還是發生異常,都返回true。 => result.isDone()
boolean isCanceller() :如果任務完成前被取消,則返回true。
boolean cancel(boolean mayInterruptRunning) :如果任務還沒開始,執行cancel(...)方法將返回false;如果任務已經啟動,執行cancel(true)方法將以中斷執行此任務線程的方式來試圖停止任務,如果停止成功,返回true;
當任務已經啟動,執行cancel(false)方法將不會對正在執行的任務線程產生影響(讓線程正常執行到完成),此時返回false;
當任務已經完成,執行cancel(...)方法將返回false。mayInterruptRunning參數表示是否中斷執行中的線程。
實際上Future提供了3種功能:
- (1)能夠中斷執行中的任務
- (2)判斷任務是否執行完成
- (3)獲取任務執行完成后的結果
個人博客 蝸牛
