一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中的Runnable,Callable,Future,FutureTask的比較

Java中的Runnable,Callable,Future,FutureTask的比較

2020-08-15 17:06Java之家 Java教程

這篇文章主要介紹了Java中的Runnable,Callable,Future,FutureTask的比較的相關資料,需要的朋友可以參考下

Java中的Runnable,Callable,Future,FutureTask的比較

Java中存在Runnable、Callable、Future、FutureTask這幾個與線程相關的類或者接口,在Java中也是比較重要的幾個概念,我們通過下面的簡單示例來了解一下它們的作用于區別。

Runnable

其中Runnable應該是我們最熟悉的接口,它只有一個run()函數,用于將耗時操作寫在其中, 該函數沒有返回值 。然后使用某個線程去執行該runnable即可實現多線程,Thread類在調用start()函數后就是執行的是Runnable的run()函數。Runnable的聲明如下 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@FunctionalInterface
public interface Runnable {
  /**
   * When an object implementing interface <code>Runnable</code> is used
   * to create a thread, starting the thread causes the object's
   * <code>run</code> method to be called in that separately executing
   * thread.
   * <p>
   * The general contract of the method <code>run</code> is that it may
   * take any action whatsoever.
   *
   * @see   java.lang.Thread#run()
   */
  public abstract void run();
}

Callable

Callable與Runnable的功能大致相似,Callable中有一個call()函數,但是 call()函數有返回值 ,而Runnable的run()函數不能將結果返回給客戶程序。Callable的聲明如下 :

?
1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
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;
}

可以看到,這是一個泛型接口,call()函數返回的類型就是客戶程序傳遞進來的V類型。

Future

Executor就是Runnable和Callable的調度容器,Future就是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果、設置結果操作。get方法會阻塞,直到任務返回結果(Future簡介)。Future聲明如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
* @see FutureTask
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param <V> The result type returned by this Future's {@code get} method
 */
public interface Future<V> {
 
  /**
   * Attempts to cancel execution of this task. This attempt will
   * fail if the task has already completed, has already been cancelled,
   * or could not be cancelled for some other reason. If successful,
   * and this task has not started when {@code cancel} is called,
   * this task should never run. If the task has already started,
   * then the {@code mayInterruptIfRunning} parameter determines
   * whether the thread executing this task should be interrupted in
   * an attempt to stop the task.
   *
   * <p>After this method returns, subsequent calls to {@link #isDone} will
   * always return {@code true}. Subsequent calls to {@link #isCancelled}
   * will always return {@code true} if this method returned {@code true}.
   *
   * @param mayInterruptIfRunning {@code true} if the thread executing this
   * task should be interrupted; otherwise, in-progress tasks are allowed
   * to complete
   * @return {@code false} if the task could not be cancelled,
   * typically because it has already completed normally;
   * {@code true} otherwise
   */
  boolean cancel(boolean mayInterruptIfRunning);
 
  /**
   * Returns {@code true} if this task was cancelled before it completed
   * normally.
   *
   * @return {@code true} if this task was cancelled before it completed
   */
  boolean isCancelled();
 
  /**
   * Returns {@code true} if this task completed.
   *
   * Completion may be due to normal termination, an exception, or
   * cancellation -- in all of these cases, this method will return
   * {@code true}.
   *
   * @return {@code true} if this task completed
   */
  boolean isDone();
 
  /**
   * Waits if necessary for the computation to complete, and then
   * retrieves its result.
   *
   * @return the computed result
   * @throws CancellationException if the computation was cancelled
   * @throws ExecutionException if the computation threw an
   * exception
   * @throws InterruptedException if the current thread was interrupted
   * while waiting
   */
  V get() throws InterruptedException, ExecutionException;
 
  /**
   * Waits if necessary for at most the given time for the computation
   * to complete, and then retrieves its result, if available.
   *
   * @param timeout the maximum time to wait
   * @param unit the time unit of the timeout argument
   * @return the computed result
   * @throws CancellationException if the computation was cancelled
   * @throws ExecutionException if the computation threw an
   * exception
   * @throws InterruptedException if the current thread was interrupted
   * while waiting
   * @throws TimeoutException if the wait timed out
   */
  V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
}

FutureTask

FutureTask則是一個RunnableFuture< V>,而RunnableFuture實現了Runnbale又實現了Futrue< V>這兩個接口:

?
1
2
3
public class FutureTask<V> implements RunnableFuture<V> {
......
}

RunnableFuture

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * A {@link Future} that is {@link Runnable}. Successful execution of
 * the {@code run} method causes completion of the {@code Future}
 * and allows access to its results.
 * @see FutureTask
 * @see Executor
 * @since 1.6
 * @author Doug Lea
 * @param <V> The result type returned by this Future's {@code get} method
 */
public interface RunnableFuture<V> extends Runnable, Future<V> {
  /**
   * Sets this Future to the result of its computation
   * unless it has been cancelled.
   */
  void run();
}

另外FutureTask還可以包裝Runnable和Callable< V>, 由構造函數注入依賴。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
   * Creates a {@code FutureTask} that will, upon running, execute the
   * given {@code Callable}.
   *
   * @param callable the callable task
   * @throws NullPointerException if the callable is null
   */
  public FutureTask(Callable<V> callable) {
    if (callable == null)
      throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;    // ensure visibility of callable
  }
 
  /**
   * Creates a {@code FutureTask} that will, upon running, execute the
   * given {@code Runnable}, and arrange that {@code get} will return the
   * given result on successful completion.
   *
   * @param runnable the runnable task
   * @param result the result to return on successful completion. If
   * you don't need a particular result, consider using
   * constructions of the form:
   * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
   * @throws NullPointerException if the runnable is null
   */
  public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;    // ensure visibility of callable
  }

可以看到,Runnable注入會被Executors.callable()函數轉換為Callable類型,即FutureTask最終都是執行Callable類型的任務。該適配函數的實現如下 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
   * Returns a {@link Callable} object that, when
   * called, runs the given task and returns the given result. This
   * can be useful when applying methods requiring a
   * {@code Callable} to an otherwise resultless action.
   * @param task the task to run
   * @param result the result to return
   * @param <T> the type of the result
   * @return a callable object
   * @throws NullPointerException if task null
   */
  public static <T> Callable<T> callable(Runnable task, T result) {
    if (task == null)
      throw new NullPointerException();
    return new RunnableAdapter<T>(task, result);
  }

RunnableAdapter適配器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
   * A callable that runs given task and returns given result
   */
  static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    RunnableAdapter(Runnable task, T result) {
      this.task = task;
      this.result = result;
    }
    public T call() {
      task.run();
      return result;
    }
  }

由于FutureTask實現了Runnable,因此它既可以通過Thread包裝來直接執行,也可以提交給ExecuteService來執行。并且還可以直接通過get()函數獲取執行結果,該函數會阻塞,直到結果返回。

因此FutureTask既是Future、Runnable,又是包裝了Callable(如果是Runnable最終也會被轉換為Callable ), 它是這兩者的合體。

完整示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.stay4it.rx;
 
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;
import java.util.concurrent.FutureTask;
 
public class FutureTest {
 
  public static class Task implements Runnable {
 
    @Override
    public void run() {
      // TODO Auto-generated method stub
      System.out.println("run");
    }
 
  }
  public static class Task2 implements Callable<Integer> {
 
    @Override
    public Integer call() throws Exception {
      System.out.println("call");
      return fibc(30);
    }
 
  }
 
   /**
   * runnable, 無返回值
   */
  public static void testRunnable(){
    ExecutorService executorService = Executors.newCachedThreadPool();
 
    Future<String> future = (Future<String>) executorService.submit(new Task());
    try {
      System.out.println(future.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
 
    executorService.shutdown();
  }
 
  /**
   * Callable, 有返回值
   */
  public static void testCallable(){
    ExecutorService executorService = Executors.newCachedThreadPool();
 
    Future<Integer> future = (Future<Integer>) executorService.submit(new Task2());
    try {
      System.out.println(future.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
 
    executorService.shutdown();
  }
 
   /**
   * FutureTask則是一個RunnableFuture<V>,即實現了Runnbale又實現了Futrue<V>這兩個接口,
   * 另外它還可以包裝Runnable(實際上會轉換為Callable)和Callable
   * <V>,所以一般來講是一個符合體了,它可以通過Thread包裝來直接執行,也可以提交給ExecuteService來執行
   * ,并且還可以通過v get()返回執行結果,在線程體沒有執行完成的時候,主線程一直阻塞等待,執行完則直接返回結果。
   */
  public static void testFutureTask(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(new Task2());
 
    executorService.submit(futureTask);
    try {
      System.out.println(futureTask.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
 
    executorService.shutdown();
  }
 
   /**
   * FutureTask則是一個RunnableFuture<V>,即實現了Runnbale又實現了Futrue<V>這兩個接口,
   * 另外它還可以包裝Runnable(實際上會轉換為Callable)和Callable
   * <V>,所以一般來講是一個符合體了,它可以通過Thread包裝來直接執行,也可以提交給ExecuteService來執行
   * ,并且還可以通過v get()返回執行結果,在線程體沒有執行完成的時候,主線程一直阻塞等待,執行完則直接返回結果。
   */
  public static void testFutureTask2(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(new Runnable() {
 
      @Override
      public void run() {
        // TODO Auto-generated method stub
        System.out.println("testFutureTask2 run");
      }
    },fibc(30));
 
    executorService.submit(futureTask);
    try {
      System.out.println(futureTask.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
 
    executorService.shutdown();
  }
 
 
 
  public static void main(String[] args) {
 
    testCallable();
 
  }
 
  /**
   * 效率低下的斐波那契數列, 耗時的操作
   *
   * @param num
   * @return
   */
  static int fibc(int num) {
    if (num == 0) {
      return 0;
    }
    if (num == 1) {
      return 1;
    }
    return fibc(num - 1) + fibc(num - 2);
  }
 
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品一区二区国产 | 男人午夜禁片在线观看 | 亚洲成综合人影院在院播放 | 亚洲日韩中文字幕一区 | 办公室大战秘书呻吟 | 免费一级特黄特色大片在线观看 | 丁香六月色| 精品国产福利在线 | 精品免费视频 | 毛片免费视频观看 | 欧美日韩第二页 | yellow在线| 亚洲国产成人在线 | 欧美成人禁片在线观看俄罗斯 | 日韩亚洲欧美综合一区二区三区 | 亚洲AV国产精品无码精 | 免费黄色片网站 | 成人精品一区二区三区 | 精品国产mmd在线观看 | a一区二区三区视频 | 91精品国产亚洲爽啪在线影院 | 国产精品成人一区二区1 | 国产精品一区二区三区久久 | 91精品国产在线 | 色综色| 处女呦呦 | 亚洲AV永久无码精品老司机蜜桃 | 亚洲国产欧美在线人网站 | 2020最新韩国理论三级0k | 无人在线高清免费看 | 国产日韩成人 | 欧美vpswindows | 日本一区二区三区久久精品 | 日本一区二区视频在线观看 | 精品视频免费在线 | 91国语精品自产拍在线观看一 | 欧美老少| 高人先生免费观看全集 | 亚洲精品国产精品国自产观看 | 99热久久国产精品这里 | 精品欧美日韩一区二区三区 |