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. git乱码问题

    直接看连接吧. http://my.oschina.net/lujian863/blog/168837

  2. iOS UIWebView加载时添加进度条

    标注:此框架仅适合UIWebView  对iOS8后新出的WKWebView不适用,当然,你可以尝试修改框架里的几个代理方法. 框架是:NJKWebViewProgress 导入头文件 #import ...

  3. python视频教程大全

    python3英文视频教程(全87集) http://pan.baidu.com/s/1dDnGBvV python从入门到精通视频(全60集)链接:http://pan.baidu.com/s/1e ...

  4. LVM 创建分区扩展分区记录

    LVM 原理   图片来自百度百科   测试环境centOS 7                 LVM version:     2.02.115(2)-RHEL7 (2015-01-28)     ...

  5. BaiduMap开发,获取公交站点信息。

    可能有些人会出现无法导入overlayutil的错误,这是因为BaiduMap里面的包把这部分删除掉了,并且官方没有给出说明,这个地方以前也是让我折腾了很久. 不知道现在有没有说明这个问题,如果需要这 ...

  6. 【SQL】SQL2012 导入导出报错,未在计算机上注册...

    导出时报错: 如图: 解决方法:下载插件: 下载地址:http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463 ...

  7. RealSense 3D实感体验:前景广阔目前应用少

    腾讯数码讯(周硕)在去年的IDF大会上,英特尔着重展示了其全新的RealSense 3D实感技术,而厚度仅6mm堪称史上最薄平板的戴尔Venue 8 7000也成为首个搭载RealSense技术的产品 ...

  8. SQL SERVER NVARCHAR字段INSERT 中文乱码问题解决

    INSERT INTO IPatient ( UID, PatientNo, PatientName, PatientGender, Birthday, BloodType, Country, Nat ...

  9. yii 隐藏index.php的步骤

    Apache 1.开启apache的mod_rewrite模块       去掉LoadModule rewrite_module modules/mod_rewrite.so前的“#”符号     ...

  10. C++之运算符重载(2)

    上一节主要讲解了C++里运算符重载函数,在看了单目运算符(++)重载的示例后,也许有些朋友会问这样的问题.++自增运算符在C或C++中既可以放在操作数之前,也可以放在操作数之后,但是前置和后置的作用又 ...