1. 程式人生 > >JAVA-Runnable、Callable、FutureTask

JAVA-Runnable、Callable、FutureTask

cep 返回值 使用 isp 線程 允許 tin pat timeout

通常,創建線程的執行單元有兩種,一種是直接繼承 Thread,另外一種就是實現 Runnable 接口。

但這兩種都有一個問題就是無法有返回值,且子線程在執行過程中無法拋出異常。想線程有返回值,可以使用 Callable 來創建執行單元。

Runnable

一個接口,沒有返回值

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Callable

一個接口,有返回值,且允許拋出異常

@FunctionalInterface
public interface
Callable<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);
    return
ftask; } 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; }
View Code

使用示例

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