Java多线程编程:Callable、Future和FutureTask浅析
通过前面几篇的学习,我们知道创建线程的方式有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,那如果我们想要获取返回结果该如何实现呢?还记上一篇Executor框架结构中提到的Callable接口和Future接口吗?,是的,从Java SE 5.0开始引入了Callable和Future,通过它们构建的线程,在任务执行完成后就可以获取执行结果,今天我们就来聊聊线程创建的第三种方式,那就是实现Callable接口。
- public interface Runnable {
- public abstract void run();
- }
而Callable的接口定义如下
- public interface Callable<V> {
- V call() throws Exception;
- }
该接口声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常。嗯,对该接口我们先了解这么多就行,下面我们来说明如何使用,前篇文章我们说过,无论是Runnable接口的实现类还是Callable接口的实现类,都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行,ThreadPoolExecutor或ScheduledThreadPoolExecutor都实现了ExcutorService接口,而因此Callable需要和Executor框架中的ExcutorService结合使用,我们先看看ExecutorService提供的方法:
- <T> Future<T> submit(Callable<T> task);
- <T> Future<T> submit(Runnable task, T result);
- Future<?> submit(Runnable task);
- public static Callable<Object> callable(Runnable task)
- public static <T> Callable<T> callable(Runnable task, T result)
- public interface Future<V> {
- boolean cancel(boolean mayInterruptIfRunning);
- boolean isCancelled();
- boolean isDone();
- V get() throws InterruptedException, ExecutionException;
- V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
- }
- public class FutureTask<V> implements RunnableFuture<V> {
FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
- public interface RunnableFuture<V> extends Runnable, Future<V> {
- void run();
- }
下面我们再来看看FutureTask的方法执行示意图(方法和Future接口基本是一样的,这里就不过多描述了)
- public FutureTask(Callable<V> callable) {
- }
- public FutureTask(Runnable runnable, V result) {
- }
- package com.zejian.Executor;
- import java.util.concurrent.Callable;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:02:42
- * @decrition Callable接口实例
- */
- public class CallableDemo implements Callable<Integer> {
- private int sum;
- @Override
- public Integer call() throws Exception {
- System.out.println("Callable子线程开始计算啦!");
- Thread.sleep(2000);
- for(int i=0 ;i<5000;i++){
- sum=sum+i;
- }
- System.out.println("Callable子线程计算结束!");
- return sum;
- }
- }
Callable执行测试类如下:
- package com.zejian.Executor;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:05:43
- * @decrition callable执行测试类
- */
- public class CallableTest {
- public static void main(String[] args) {
- //创建线程池
- ExecutorService es = Executors.newSingleThreadExecutor();
- //创建Callable对象任务
- CallableDemo calTask=new CallableDemo();
- //提交任务并获取执行结果
- Future<Integer> future =es.submit(calTask);
- //关闭线程池
- es.shutdown();
- try {
- Thread.sleep(2000);
- System.out.println("主线程在执行其他任务");
- if(future.get()!=null){
- //输出获取到的结果
- System.out.println("future.get()-->"+future.get());
- }else{
- //输出获取到的结果
- System.out.println("future.get()未获取到结果");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("主线程在执行完成");
- }
- }
|
Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
future.get()-->12497500
主线程在执行完成
|
- package com.zejian.Executor;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- import java.util.concurrent.FutureTask;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:05:43
- * @decrition callable执行测试类
- */
- public class CallableTest {
- public static void main(String[] args) {
- // //创建线程池
- // ExecutorService es = Executors.newSingleThreadExecutor();
- // //创建Callable对象任务
- // CallableDemo calTask=new CallableDemo();
- // //提交任务并获取执行结果
- // Future<Integer> future =es.submit(calTask);
- // //关闭线程池
- // es.shutdown();
- //创建线程池
- ExecutorService es = Executors.newSingleThreadExecutor();
- //创建Callable对象任务
- CallableDemo calTask=new CallableDemo();
- //创建FutureTask
- FutureTask<Integer> futureTask=new FutureTask<>(calTask);
- //执行任务
- es.submit(futureTask);
- //关闭线程池
- es.shutdown();
- try {
- Thread.sleep(2000);
- System.out.println("主线程在执行其他任务");
- if(futureTask.get()!=null){
- //输出获取到的结果
- System.out.println("futureTask.get()-->"+futureTask.get());
- }else{
- //输出获取到的结果
- System.out.println("futureTask.get()未获取到结果");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("主线程在执行完成");
- }
- }
|
Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
futureTask.get()-->12497500
主线程在执行完成
|
Java多线程编程:Callable、Future和FutureTask浅析的更多相关文章
- Java 并发编程——Callable+Future+FutureTask
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】
Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...
- Java多线程的Callable, Future, FutureCallback
Callable可以看成是一个增强版的Runnable, 带返回结果, 需要通过Future或者FutureTask来提交任务或运行线程, 然后通过Future/FutureTask的get方法得到返 ...
- Java多线程:Callable,Future,FutureTask
一.Future Future和Callable基本是成对出现的,Callable负责产生结果,Future负责获取结果. 1.Callable接口类似于Runnable,只是Runnable ...
- Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)
java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)java多线程同步以及线程间通信详解&消费者生产者模式&死锁& ...
- Java - 32 Java 多线程编程
Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特别 ...
- Java多线程编程(学习笔记)
一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...
- Java-Runoob-高级教程: Java 多线程编程
ylbtech-Java-Runoob-高级教程: Java 多线程编程 1.返回顶部 1. Java 多线程编程 Java 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流, ...
随机推荐
- 解决Android中图片圆角——.9图
目录: 一.问题概述 二..9图介绍 三..9图制作 1.开发工具 2.打开图片 3.制作图片 4.保存图片 一.问题概述 在html开发中,可以通过设置css的border-radius来设置圆角 ...
- bp算法中为什么会产生梯度消失?
作者:维吉特伯链接:https://www.zhihu.com/question/49812013/answer/148825073来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- (转)HLSL,函数列表
中文列表 函数名 说明 abs 计算输入值的绝对值. acos 返回输入值反余弦值. all 测试非0值. any 测试输入值中的任何非零值. asin 返回输入值的反正弦值. atan 返回输入值的 ...
- Mysql写入中文出错
本地调试好像正常,服务器运行报错: UnicodeEncodeError: 'latin-1' codec can't encode character u'\u5206' in position 2 ...
- mongodb最大连接数、最大连接数修改
mongodb最大连接数是20000. 所以业界流传一段话,千万级以下的用mysql.千万级以上的用mongodb,亿级以上的用hadoop. 查看mongodb最大连接数 mongodb ...
- SpringMVC验证框架Validation特殊用法
基本用法不说了,网上例子很多,这里主要介绍下比较特殊情况下使用的方法. 1. 分组 有的时候,我们对一个实体类需要有多中验证方式,在不同的情况下使用不同验证方式,比如说对于一个实体类来的id来说,保存 ...
- javascript编程思想
javascript编程开发修炼之道 提要文摘附注: 本文的核心内容是围绕javascript前端开发的编程技术要素,来深入地探讨编写高质量的javascript代码的方法.技巧.规范和最佳实践, ...
- JAVA中JDBC连接Mysql数据库简单测试
一.引用库 maven库:mysql:mysql-connector-java:6.0.6 二.SDK环境 JAVA JDK10 三.测试代码 package com.mysql.mysqlconne ...
- ExtJs4.2中Tab选项卡的右击关闭其它和关闭当前功能不准确的解决方法
一.ExtJs4.2中Tab选项卡的右击关闭其它和关闭当前功能不准确的解决方法 二.找到ux目录下的TabCloseMenu.js文件,将内容替换成下面代码. 三.代码: /** * Plugin f ...
- JAVA设计模式——第 1 章 策略模式【Strategy Pattern】(转)
刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜陪了夫人又折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景 ...