Callable

java5之前是没有返回值的,Java5新增了Callable接口获得线程的返回值,可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。Callable的call方法可以根据你传入的泛型参数返回对应类型的数据。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。

示例:

package thread_Callable;
import java.util.concurrent.*;
public class Callable_Thread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//创建两个有返回值的任务
Callable c1 = new MyCallable("A");
Callable c2 = new MyCallable("B");
//执行任务并获取Future对象
Future f1 = pool.submit(c1);
Future f2 = pool.submit(c2);
//从Future对象上获取任务的返回值,并输出到控制台
System.out.println(">>>"+f1.get().toString());
System.out.println(">>>"+f2.get().toString());
//关闭线程池
pool.shutdown();
}
} class MyCallable implements Callable {
private String oid;
MyCallable(String oid) {
this.oid = oid;
}
@Override
public Object call() throws Exception {
return oid+"任务返回的内容";
}
}

结果:
>>>A任务返回的内容
>>>B任务返回的内容

在Future接口中声明了5个方法,下面依次解释每个方法的作用:

cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。

isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。

isDone方法表示任务是否已经完成,若任务完成,则返回true;

get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

 get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。

  也就是说Future提供了三种功能:

  1)判断任务是否完成;

  2)能够中断任务;

  3)能够获取任务执行结果。

FutureTask

我们先来看一下FutureTask的实现:

  public class FutureTask<V> implements RunnableFuture<V>

FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:

  public interface RunnableFuture<V> extends Runnable, Future<V> 

可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

FutureTask提供了2个构造器:

public FutureTask(Callable<V> callable) {

}

public FutureTask(Runnable runnable, V result) {

}

事实上,FutureTask是Future接口的一个唯一实现类。

package thread_Callable;

import java.util.concurrent.*;

/**
* User: 杨永生
* Date: 18:39 2017/8/14
* Email: kevin@hiibook.com
*/
public class Callable_FutureTask {
public static void main(String[] args) {
//第一种方式
ExecutorService executor = Executors.newCachedThreadPool();
MyCallable2 task = new MyCallable2();
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
executor.submit(futureTask);
executor.shutdown();
//第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
/*Task task = new Task();
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
Thread thread = new Thread(futureTask);
thread.start();*/
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("主线程在执行任务");
try {
System.out.println("task运行结果"+futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("所有任务执行完毕");
}
}
class MyCallable2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("子线程在进行计算");
Thread.sleep(3000);
int sum = 0;
for(int i=0;i<100;i++)
sum += i;
return sum;
}
}

Callable接口--有返回值的线程的更多相关文章

  1. Java Callable接口——有返回值的线程

    实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行.<线程等待——CountDownLatch使用>中我们介绍了CountDownLatch的使用,通过使用CountDow ...

  2. java使用Callable创建又返回值的线程

    并发编程使我们可以将程序分为很多个分离的,相互之间独立的任务,通过使用多线程的机制,将每个任务都会有一个执行线程来单独的驱动,一个线程是 进程中一个单一顺序控制流,一个进程可以拥有多个线程,也就相当于 ...

  3. java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

    用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...

  4. Java线程:新特征-有返回值的线程

    http://lavasoft.blog.51cto.com/62575/222082/ Java线程:新特征-有返回值的线程 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 ...

  5. Java中使用有返回值的线程

    在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable,可以获取线程中的返回值,但是获取线程的返回值的时候,需 ...

  6. Java线程:新特征-有返回值的线程《转》

      原始文章   在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.   现在Java终于有可返回值的任务(也可以叫做线程)了. ...

  7. JMeter-一个接口的返回值作为输入传给其他接口

    背景: 在用JMeter写接口case,遇到一种情况,接口1查看列表接口,接口2查看详情接口,接口2需要传入接口1列表的第一条数据的id 解决方案: 首先放一下总体截图 具体步骤 1-新建一个Thre ...

  8. postman 上一个接口的返回值作为下一个接口的入参

    在使用postman做接口测试的时候,在多个接口的测试中,如果需要上一个接口的返回值作为下一个接口的入参,其基本思路是: 1.获取上一个接口的返回值 2.将返回值设置成环境变量或者全局变量 3.设置下 ...

  9. 接口需要上一个接口的返回值(unittest)

    import unittest,requests ''' 使用unittest框架的时候,这个接口需要上一个接口的返回值 ''' class Test_case(unittest.TestCase): ...

随机推荐

  1. 9.9 翻译系列:数据注解特性之--MaxLength 【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/maxlength-minlength-dataannotations-attribut ...

  2. Redis 学习笔记(十二)Redis 复制功能详解 ----- (error) READONLY You can't write against a read only slave

    Redis 复制(Replication)1. 复制介绍分布式数据库为了获取更大的存储容量和更高的并发访问量,会将原来集中式数据库中的数据分散存储到多个通过网络连接的数据存储节点上.Redis为了解决 ...

  3. 【Spark调优】:如果实在要shuffle,使用map侧预聚合的算子

    因业务上的需要,无可避免的一些运算一定要使用shuffle操作,无法用map类的算子来替代,那么尽量使用可以map侧预聚合的算子. map侧预聚合,是指在每个节点本地对相同的key进行一次聚合操作,类 ...

  4. 手把手教你如何用eclipse搭建前端开发环境

    3.创建静态web工程 打开eclipse,选择file,new project 或者 new other...,选择web项中的static web project ,next. 输入你的项目名,如 ...

  5. day 75vue 脚手架学习 脚手架的使用

    前情提要: vue 自定化开发工具  (vue-cli的使用) 一:安装脚手架,以及准备 1: 下载地址, https://nodejs.org/en/download/ 2:如果下载成功,在cmd ...

  6. [转]KMP算法理解及java实现

    这大概是我看的最好懂的KMP算法讲解了,不过我还只弄懂了大概思想,算法实现我到时候用java实现一遍 出处:知乎 https://www.zhihu.com/question/21923021/ans ...

  7. Java之基础学习(数据类型、运算符、分支语句和循环语句)

    在工作用得比较多的是shell和python编程,对于java以前也学习过,使用很少,这次借朋友推荐的java视频教程来温习下. 也是因为现在很多开源测试工具使用java编写的,学习一下更有助于测试工 ...

  8. ACM学习<一>

    c++指针|指针入门 什么是指针? 其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据.这是一个非常重要的概念,有很多 ...

  9. Hadoop2源码分析-YARN RPC 示例介绍

    1.概述 之前在<Hadoop2源码分析-RPC探索实战>一文当中介绍了Hadoop的RPC机制,今天给大家分享关于YARN的RPC的机制.下面是今天的分享目录: YARN的RPC介绍 Y ...

  10. vs2015+qt5.9.7配置跨平台的工程

    环境:vs2015 update 3 + qt 5.9.7 问题:代码中存在中文无法编译 附加目的:支持跨平台 问题分析:代码的编码格式导致中文编译错误,windows默认gb2312编码,qt默认u ...