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 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流, ...
随机推荐
- 使用tensorflow的lstm网络进行时间序列预测
https://blog.csdn.net/flying_sfeng/article/details/78852816 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...
- mysql 批量数据循环插入
双重循环插入 DELIMITER ;; CREATE PROCEDURE test_insert() BEGIN DECLARE a INT DEFAULT 1; DECLARE b TINYINT ...
- Struts2的Action继承ActionSupport时,利用AOP来拦截Action出现NoSuchMethodException
参考:http://zhanghua.1199.blog.163.com/blog/static/46449807201111139501298/ 做项目的时候,由于要用到在Struts2的Actio ...
- MODBUS协议整理——功能码简述
1.Modbus简介——来自维基百科 Modbus是一种串行通信协议,是Modicon于1979年,为使用可编程逻辑控制器(PLC)而发表的.Modbus是工业领域通信协议的业界标准,并且现在是工业电 ...
- border-color: transparent rgb(255, 48, 48) transparent transparent;
border-color: transparent rgb(255, 48, 48) transparent transparent;
- Direct2D教程III——几何(Geometry)对象
目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...
- OpenGL ES3.0
到今天,喜欢上了非常酷的图片处理和游戏,经了解,大部分都要使用opengl es,所以准备开始学习,然后深入学习cocos2d,GPUImage.平台为IOS OpenGL ES OpenGL ES ...
- ArcGIS10.6了解一下
因为计算机水平不断更新,ESRI不得不重新倾力打造下一代ArcMap,叫ArcGIS Pro,现在ArcGIS Pro功能有一定地突显,但还不够强大和稳定:而ArcGIS Desktop方面没有什么大 ...
- 第八周(1) Word信函与邮件
第八周(1) Word信函与邮件 教学时间 2013-4-15 教学课时 2 教案序号 13 教学目标 1.学会使用word制作信封和标签2.理解邮件合并的概念和功能3.学会利用邮件合并批量制作文档 ...
- 使用Json.Net解决MVC中各种json操作
最近收集了几篇文章,用于替换MVC中各种json操作,微软mvc当然用自家的序列化,速度慢不说,还容易出问题,自定义性也太差,比如得特意解决循环引用的问题,比如datetime的序列化格式,比如性能. ...