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 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流, ...
随机推荐
- 屌丝就爱尝鲜头——java8总结晒一晒
前两节讨论了那么多,这节就是两个议题,讨论了新增的日期的api,再说一说我的Java8的一些心得体会了. 首先,我们必须要搞清楚Java 8 为什么要增加新的日期的api,这是由于老的日期api非常的 ...
- 从头认识java-18.2 主要的线程机制(4)-优先级
这一章节我们来讨论一下多线程的优先级问题. 1.样例: package com.ray.ch17; public class Test { public static void main(String ...
- C#字符串比较
正确写法1 bool bTemplatecontent2 = strtemplateContentInDB.Equals(strTemplateContentInDesignPanel, String ...
- Intellij IDEA 配置Subversion插件时效解决方法
在使用Intellij的过程中,突然发现svn不起效了,在VCS–>Checkout from Version Control中也未发现Subversion这一项.如下图: 一.原因查找 经过分 ...
- 【Python】torrentParser1.01
在昨天的版本上做了一些改进,如增加getAll,修改getSingleFileName等 代码: #-------------------------------------------------- ...
- 提高Mxd地图渲染出图效率的方法
测试 在ArcGIS地图渲染非常耗时,特别是标注较多时,下面是做的一些性能测试 小结 1.地图渲染的数据量是显示出图速度的关键.主要注意: (1)与数据库存储的数据量关系不大.例如数据库有1万条数 ...
- FIS.js前端开发的使用说明文档
文档结构 什么是FIS 部署FIS FIS基本使用 模块定义 加载方式 调用Tangram 2.0 一.什么是FIS FIS提供了一套贯穿开发流程的开发体系和集成开发环境,为产品线提供前端开发底层架构 ...
- fread/fwrite
fread/fwrite第二个参数和第三个参数的区别以及与返回值的关系 size_t fwrite_unlocked(const void * __restrict ptr, size_t size, ...
- 微信小程序 - 自定义switch切换(示例)
点击下载:switch示例 ,适用于表单,官方switch 说明 .
- 微信小程序 - 超出文字省略组件
使用说明 sty:定义样式 text:文字 clamp: 0:代表不限制 1:超过1行省略号(默认) n:超过n行省略 点击下载:ellipsis