Home  >  Article  >  Java  >  Detailed code explanation of Callable and Future in Java concurrency thread pool

Detailed code explanation of Callable and Future in Java concurrency thread pool

黄舟
黄舟Original
2017-06-18 10:11:141497browse

This article mainly introduces Callable and Future of Java concurrency thread pool in detail, which has certain reference value. Interested friends can refer to

Callable and Future Introduction

Callable and Future are an interesting combination. We need to use them when we need to get the execution results of the thread. Callable is used to produce results and Future is used to obtain results.

1. Callable

Callable is an interface that only contains one call() method. A Callable is a task that returns a result and may throw an exception.
For ease of understanding, we can compare Callable to a Runnable interface, and Callable's call() method is similar to Runnable's run() method.
The source code of Callable is as follows:


public interface Callable<V> {
 V call() throws Exception;
}

Description: From this we can see that Callable supports generics .

2. Future

Future is an interface. It is used to represent the results of asynchronous calculations. Methods are provided to check whether the calculation is completed, to wait for the completion of the calculation, and to obtain the result of the calculation. The source code of
Future is as follows:


public interface Future<V> {
 // 试图取消对此任务的执行。
 boolean cancel(boolean mayInterruptIfRunning)

 // 如果在任务正常完成前将其取消,则返回 true。
 boolean isCancelled()

 // 如果任务已完成,则返回 true。
 boolean isDone()

 // 如有必要,等待计算完成,然后获取其结果。
 V  get() throws InterruptedException, ExecutionException;

 // 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。
 V  get(long timeout, TimeUnit unit)
  throws InterruptedException, ExecutionException, TimeoutException;
}

Description: Future is used to represent the results of asynchronous calculations. Its implementation class is FutureTask. Before explaining FutureTask, let's first look at the relationship diagram between Callable, Future and FutureTask, as follows:

Description:

(01) RunnableFuture is an interface that inherits the two interfaces Runnable and Future. The source code of RunnableFuture is as follows:


##

public interface RunnableFuture<V> extends Runnable, Future<V> {
 void run();
}

(02) FutureTask implements the RunnableFuture interface. Therefore, we also say that it implements the Future interface.

Example and source code analysis (based on JDK1.7.0_40)

Let’s first look at the basic usage of Callable and Future through an example, and then analyze the example implementation principle.


import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;

class MyCallable implements Callable {

 @Override 
 public Integer call() throws Exception {
 int sum = 0;
 // 执行任务
 for (int i=0; i<100; i++)
  sum += i;
 //return sum; 
 return Integer.valueOf(sum);
 } 
}

public class CallableTest1 {

 public static void main(String[] args) 
 throws ExecutionException, InterruptedException{
 //创建一个线程池
 ExecutorService pool = Executors.newSingleThreadExecutor();
 //创建有返回值的任务
 Callable c1 = new MyCallable();
 //执行任务并获取Future对象 
 Future f1 = pool.submit(c1);
 // 输出结果
 System.out.println(f1.get()); 
 //关闭线程池 
 pool.shutdown(); 
 }
}

Run result:


4950


Result description:

In the main thread main, create a new thread pool through newSingleThreadExecutor(). Then create the Callable object c1, and then submit c1 to the thread pool for processing through pool.submit(c1), and save the returned result to the Future object f1. Then, we get the result saved in Callable through f1.get(); finally, we close the thread pool through pool.shutdown().


1. submit()

submit() is implemented in java/util/concurrent/AbstractExecutorService.java. Its source code is as follows:


public <T> Future<T> submit(Callable<T> task) {
 if (task == null) throw new NullPointerException();
 // 创建一个RunnableFuture对象
 RunnableFuture<T> ftask = newTaskFor(task);
 // 执行“任务ftask”
 execute(ftask);
 // 返回“ftask”
 return ftask;
}

Explanation: submit() creates the RunnableFuture object ftask through newTaskFor(task). Its source code is as follows:



protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
 return new FutureTask<T>(callable);
}

2. FutureTask’s constructor
## The constructor of #FutureTask is as follows:

public FutureTask(Callable<V> callable) {
 if (callable == null)
 throw new NullPointerException();
 // callable是一个Callable对象
 this.callable = callable;
 // state记录FutureTask的状态
 this.state = NEW; // ensure visibility of callable
}

3. The run() method of FutureTask


We continue to return In the source code of submit().

After creating a new ftask object in newTaskFor(), the task will be executed through execute(ftask). At this time, ftask is executed as a Runnable object, and its run() method will eventually be called; the run() method of ftask is implemented in java/util/concurrent/FutureTask.java, and the source code is as follows:


public void run() {
 if (state != NEW ||
 !UNSAFE.compareAndSwapObject(this, runnerOffset,
     null, Thread.currentThread()))
 return;
 try {
 // 将callable对象赋值给c。
 Callable<V> c = callable;
 if (c != null && state == NEW) {
  V result;
  boolean ran;
  try {
  // 执行Callable的call()方法,并保存结果到result中。
  result = c.call();
  ran = true;
  } catch (Throwable ex) {
  result = null;
  ran = false;
  setException(ex);
  }
  // 如果运行成功,则将result保存
  if (ran)
  set(result);
 }
 } finally {
 runner = null;
 // 设置“state状态标记”
 int s = state;
 if (s >= INTERRUPTING)
  handlePossibleCancellationInterrupt(s);
 }
}

Explanation: The call() method of the Callable object will be executed in run(), and the result will eventually be saved to result and passed set(result) saves the result.   After calling the get() method of FutureTask, the value saved by set(result) is returned.

The above is the detailed content of Detailed code explanation of Callable and Future in Java concurrency thread pool. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn