启动一个线程不论使用Thread或者Runnable的时候。都是没有返回结果的。

也就是说Thread和Runnable的run()方法必须没有返回值。

public void run(){}

解决方式:

Callable和Future,一个产生结果,一个拿到结果。

简单的来一个实例demo帮助我们理解:

public class CallableAndFuture {

	/**
* @param args
*/
public static void main(String[] args) {
//单一线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future =
threadPool.submit(
new Callable<String>() {
public String call() throws Exception {
Thread.sleep(2000);
return "hello";
};
}
);
System.out.println("等待结果");
try {
System.out.println("拿到结果" + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} } }

运行结果:

等待结果

拿到结果hello

使用场景:

如果有一个非常耗时的返回值须要计算。而且这个返回值不是立马须要的话,那么就能够使用以上这样的方式,用还有一个线程去计算返回值,而当前线程在使用这个返回值之前能够做其他的操作,等到须要这个返回值时,再通过Future得到!

说明:

Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的

Callable要採用ExecutorService的submit方法提交,返回为future对象

CompletionService用于提交一组Callable任务,其take方法返回已完毕的一个Callable任务相应的Future对象

好比我同一时候种了几块地的麦子,然后就等待收割。收割时,哪块先成熟,则先收割哪块

以下我们来针对CompletionService看一个小demo

public class CallableAndFuture {

	/**
* @param args
*/
public static void main(String[] args) { ExecutorService threadPool2 = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
for(int i=1;i<=10;i++){
final int seq = i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return seq;
}
});
}
for(int i=0;i<10;i++){
try {
System.out.println(
completionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} }

运行结果:

8

6

5

7

2

1

3

10

9

4

总结:

对于多线程运行返回结果这样的需求在实际应用中还是非常少见的,此文仅仅是作为了解学习。

JAVA 并发编程-返回运行结果(Callable和Future)(九)的更多相关文章

  1. Java并发编程原理与实战三十一:Future&FutureTask 浅析

    一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...

  2. Java并发机制(9)--Callable、Future、FutureTask的使用

    Java并发编程:Callable.Future.FutureTask的使用 整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3949310.html ...

  3. Java并发编程:Callable、Future和FutureTask

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  4. (转)Java并发编程:Callable、Future和FutureTask

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  5. Java 并发编程:Callable和Future

    项目中经常有些任务需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做呢?用runnable是无法实现的,我们需要用callable实现. import java ...

  6. Java并发编程:Callable、Future和FutureTask(转)

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

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

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

  8. 15、Java并发编程:Callable、Future和FutureTask

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  9. 007 Java并发编程:Callable、Future和FutureTask

    原文https://www.cnblogs.com/dolphin0520/p/3949310.html Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述 ...

随机推荐

  1. linux wget变成000权限

    今天使用wget下载文件时出现:-bash: /usr/bin/wget: 权限不够. 查看  /usr/bin/wget 的权限为: ---------- 1 root root 357400 3月 ...

  2. Python开发环境之pyenv环境搭建

    首先到Github上下载Pyenv相应的一键安装脚本, 安装完毕,设置环境变量,设置环境变量,可以添加到个人家目录的.bashrc或.bash_profile及系统的全局的/etc/profile, ...

  3. Cisco路由器交换机基础配置

    交换机配置 交换机基本状态: switch: # ROM状态, 路由器是rommon> hostname> # 用户模式 hostname# # 特权模式 hostname(config) ...

  4. 3.3.3 使用 join 连接字段

        join 命令可以将多个文件结合在一起,每个文件里的每条记录,都共享一个键值(key),键值指的是记录中的主字段,通常会是用户名称.个人姓氏.员工编号之类的数据.举例来说,两个文件,一个列出所 ...

  5. luogu3960 列队

    参考这篇 #include <iostream> #include <cstdio> #include <vector> using namespace std; ...

  6. 前端传list,springmvc接收list的方法

    handler: function() { var baseCustomerForm = me.getAddBaseCustomerForm().getForm(); var linkStore = ...

  7. lr函数之lr_eval_string()函数的使用学习

    lr_eval_string() 函数的主要作用:返回脚本中的一个参数当前的值(从参数中取得对应的值,并且转换为一个字符串). 格式:lr_eval_string("{参数名}") ...

  8. POJ-1061青蛙的约会,扩展欧几里德求逆元!

                                                               青蛙的约会 以前不止一次看过这个题,但都没有去补..好吧,现在慢慢来做. 友情提示 ...

  9. /etc/fstab readyonly 解决办法

    阿里云主机切换地区强制升级后,“新的磁盘盘符识别为vdb1,但是在/etc/fstab中记录的挂载信息还是旧的xvdb1,导致磁盘挂载失败” 机子启动出错了. 按提示 输入 root的密码,进入以Re ...

  10. HTML介绍&常用的标签

    HTML介绍 1. web服务器本质 import socket s = socket.socket() s.bind(('127.0.0.1', 8080)) s.listen(5) while T ...