One of the advantages of the Executor framework is that you can run concurrent tasks that return a result. The Java Concurrency API achieves this with the following two interfaces:

  • Callable: This interface is similar to the Runnable interface. It has the call() method which you have to implement the logic of a task. The Callable interface is a parameterized interface, meaning you have to indicate the type of data the call() method will return.
  • Future: This interface has some methods to obtain the result generated by a Callable object and to manage its state.
/**
* This class calculates if a number is a prime number.
* It can be executed in an executor because it implements the Callable interface.
* The call() method will return a String
*/
public class PrimesCalculator implements Callable<String> { private int num; public PrimesCalculator(int num) {
this.num = num;
} /**
* Method called by the executor to execute this task
* and calculate if a number is a prime number
*/
@Override
public String call() throws Exception {
String msg = Primes.isPrime(num) ? String.format("%d is a prime number.", num)
: String.format("%d is not a prime number.", num);
TimeUnit.SECONDS.sleep(new Random().nextInt(3));
return msg;
}
} public class Main { /**
* @param args
*/
public static void main(String[] args) { // Create a ThreadPoolExecutor with fixed size. It has a maximun of two threads
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
// List to store the Future objects that control the execution of the task and
// are used to obtain the results
List<Future<Integer>> resultList=new ArrayList<>(); // Create a random number generator
Random random=new Random();
// Create and send to the executor the ten tasks
for (int i=0; i<10; i++){
Integer number=new Integer(random.nextInt(10));
FactorialCalculator calculator=new FactorialCalculator(number);
Future<Integer> result=executor.submit(calculator);
resultList.add(result);
} // Wait for the finalization of the ten tasks
do {
System.out.printf("Main: Number of Completed Tasks: %d\n",executor.getCompletedTaskCount());
for (int i=0; i<resultList.size(); i++) {
Future<Integer> result=resultList.get(i);
System.out.printf("Main: Task %d: %s\n",i,result.isDone());
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (executor.getCompletedTaskCount()<resultList.size()); // Write the results
System.out.printf("Main: Results\n");
for (int i=0; i<resultList.size(); i++) {
Future<Integer> result=resultList.get(i);
Integer number=null;
try {
number=result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.printf("Core: Task %d: %d\n",i,number);
} // Shutdown the executor
executor.shutdown(); } }

In this case, you have learned how to use the Callable interface to launch concurrent tasks that return a result. You have implemented the PrimesCalculator class that implements the Callable interface with String as the type of the result. Hence, it returns before type of the call() method.

The other critical point of this example is in the Main class. You send a Callable object to be executed in an executor using the submit() method. This method receives a Callable object as a parameter and returns a Future object that you can use with two main objectives:

  • You can control the status of the task: you can cancel the task and check if it has finished. For this purpose, you have used the isDone() method to check if the tasks had finished.
  • You can get the result returned by the call() method. For this purpose, you have used the get() method. This method waits until the Callable object has finished the execution of the call() method and has returned its result. If the thread is interrupted while the get() method is waiting for the result, it throws an InterruptedException exception. If the call() method throws an exception, this method throws an ExecutionException exception.

When you call the get() method of a Future object and the task controlled by this object hasn't finished yet, the method blocks until the task finishes. The Future interface provides another version of the get() method.

  • get(long timeout, TimeUnit unit): This version of the get method, if the result of the task isn't available, waits for it for the specified time. If the specified period of time passes and the result isn't yet available, the method returns a null value. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS.

Java Concurrency - Callable & Future的更多相关文章

  1. Java - 多线程Callable、Executors、Future

    http://blog.csdn.net/pipisorry/article/details/44341579 Introduction Callable接口代表一段能够调用并返回结果的代码; Fut ...

  2. Java Callable Future Example(java 关于Callable,Future的例子)

    Home » Java » Java Callable Future Example Java Callable Future Example April 3, 2018 by Pankaj 25 C ...

  3. Java 并发编程——Callable+Future+FutureTask

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  4. java并发--Callable、Future和FutureTask

    在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就 ...

  5. Java多线程 - Callable和Future

    已知的创建多线程的方法有继承Tread类和实现Runnable方法.此外Java还提供了Callable接口,Callable接口也提供了一个call()方法来做为线程执行体.但是call()方法与r ...

  6. java 并发runable,callable,future,futureTask

    转载自:http://www.cnblogs.com/dolphin0520/p/3949310.html package future_call; import java.util.concurre ...

  7. Java多线程Callable和Future类详解

         public interface Callable<V>    返回结果并且可能抛出异常的任务.实现者定义了一个不带任何参数的叫做 call 的方法      public in ...

  8. Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况

    如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...

  9. Java线程池(Callable+Future模式)

    转: Java线程池(Callable+Future模式) Java线程池(Callable+Future模式) Java通过Executors提供四种线程池 1)newCachedThreadPoo ...

随机推荐

  1. UVa 11971 Polygon (数学,转化)

    题意:一根长度为n的木条,随机选k个位置将其切成k+1段,问这k+1段能组成k+1条边的多边形的概率. 析:这个题,很明显和 n 是没有任何关系的,因为无论 n 是多少那切多少段都可以,只与切多少段有 ...

  2. HDU 5441 Travel (并查集+数学+计数)

    题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u ...

  3. 159. Longest Substring with At Most Two Distinct Characters

    最后更新 二刷 08-Jan-17 回头看了下一刷的,用的map,应该是int[256]的意思,后面没仔细看cuz whatever I was doing at that time.. wasnt ...

  4. ALT(预警)

    1. Alert简介 Alert是一种Oracle系统中的一种机制,它可以监视系统数据库,在规定的情况下给规定用户一个通知,通知可以是邮件或者其他形式,在标注的系统和客户化系统中都是可以定义使用的 2 ...

  5. Codeforces Gym 100286B Blind Walk DFS

    Problem B. Blind WalkTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/cont ...

  6. mac 环境下mysql 不能删除schema问题的解决办法

    首先说明下问题环境,我是在mac机器上安装的mysql+workbench. 在删除一个数据库的时候,出现error dropping database cant rmdir ./test 的问题. ...

  7. delphi Sender和Tag的用法

    var  Form1: TForm1;  SelectedColor:TColor;//clBlack; //Defaultimplementation{$R *.dfm}procedure TFor ...

  8. Html页中使用OCX控件

    原文:http://blog.csdn.net/mouse8166/article/details/5515657 最近准备开发一个b/s架构的应用程序需要用到activeX控件,web服务器尚未进入 ...

  9. JavaScipt call和apply用法

    转:http://www.cnblogs.com/wupeng/p/3477879.html Javascript call与apply记录 [注]:记录自己对javascript中call与appl ...

  10. Android 事件监听处理

    事件监听的处理模型包括三个成员:事件源.事件以及事件监听器. 基于监听的事件处理模型一般包括几个步骤: 1.获取普通界面组件: 2.实现事件监听器类 3.将监听器对象注冊给普通组件 当事件源上发生指定 ...