JAVA-Runnable、Callable、FutureTask
阿新 • • 發佈:2019-05-13
cep 返回值 使用 isp 線程 允許 tin pat timeout
通常,創建線程的執行單元有兩種,一種是直接繼承 Thread,另外一種就是實現 Runnable 接口。
但這兩種都有一個問題就是無法有返回值,且子線程在執行過程中無法拋出異常。想線程有返回值,可以使用 Callable 來創建執行單元。
Runnable
一個接口,沒有返回值
@FunctionalInterface public interface Runnable { public abstract void run(); }
Callable
一個接口,有返回值,且允許拋出異常
@FunctionalInterface public interfaceCallable<V> { V call() throws Exception; }
FutureTask
Future 接口的實現類,用於包裝 Runnable 或 Callable,用於獲得線程的執行結果,且允許中斷線程執行過程,還可用於判斷線程是否執行完成
/** * boolean isCancelled() * 任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true。 * * V get() * 獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回 * * V get(long timeout, TimeUnit unit) * 在指定時間內嘗試獲取執行結果。若超時則拋出超時異常 * * Boolean isDone() * 任務是否已經完成(包括正常執行完畢、執行異常或者任務取消),若任務完成,則返回 true * * boolean cancel(boolean mayInterruptInRunning) * 取消任務,如果取消任務成功則返回 true,如果取消任務失敗則返回 false * 參數 mayInterruptIfRunning 表示是否允許取消正在執行卻沒有執行完畢的任務,如果設置 true,則表示可以取消正在執行過程中的任務 * 如果任務已經完成,則無論 mayInterruptIfRunning 為 true 還是 false,此方法肯定返回 false,即如果取消已經完成的任務會返回 false * 如果任務正在執行,若 mayInterruptIfRunning 設置為 true,則返回 true,若 mayInterruptIfRunning 設置為 false,則返回 false * 如果任務還沒有執行,則無論 mayInterruptIfRunning 為 true 還是 false,肯定返回 true*/
線程池中的 (java.util.concurrent.AbstractExecutorService)submit 方法,將任務包裝成 RunnableFuture 再執行
public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); returnView Codeftask; } public <T> Future<T> submit(Runnable task, T result) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task, result); execute(ftask); return ftask; } public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
使用示例
Runnable runnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }; // 無返回值 FutureTask<?> rFutureTask = new FutureTask<Void>(runnable, null); // 返回指定值 // FutureTask<String> rFutureTask = new FutureTask<String>(runnable, "OK"); System.out.println(rFutureTask.isDone()); new Thread(rFutureTask).start(); Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(1000); return Thread.currentThread().getName(); } }; FutureTask<String> cFutureTask = new FutureTask(callable); new Thread(cFutureTask).start(); System.out.println(cFutureTask.isCancelled()); // 獲取結果 System.out.println(cFutureTask.get());
https://www.cnblogs.com/dolphin0520/p/3949310.html
https://www.cnblogs.com/maypattis/p/5827671.html
JAVA-Runnable、Callable、FutureTask