激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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);
  }
 
}

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一级一级片 | 亚洲精品欧美二区三区中文字幕 | 免费a级观看 | 亚洲片在线 | 黄色网址免费在线播放 | 91视频网 | 亚州综合 | 欧美激情天堂 | 高清国产午夜精品久久久久久 | 国产精品久久久久久久久久尿 | 中国毛片在线观看 | 国产日本欧美在线观看 | 免费一级高清毛片 | 久久久av亚洲男天堂 | 久草在线高清 | 欧美性成人 | 中文字幕在线观看视频一区 | 黄色aaa视频 | 亚洲精品7777xxxx青睐 | 黄色毛片a级 | 欧日一级片 | 午夜激情视频网站 | 草久网| av免费在线观看av | 国产免费久久久久 | 国产美女自拍av | 亚洲av毛片在线观看 | 99国产精品国产免费观看 | 亚洲一区 国产精品 | 国产免费www | 91成人影院 | 亚洲午夜视频在线 | 天天干天天透 | 国产欧美日韩视频在线观看 | 欧美一级做a | 91综合在线观看 | 久精品国产 | 欧美成人精品h版在线观看 久久久久久三区 | 欧美精品一区二区三区四区 | 草妞视频 | 国产91精品一区二区麻豆亚洲 |