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 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流, ...
随机推荐
- iOS 里RGB 配色 UIColor colorWithRed
//比如rgb 色值为73. 148 .230 那么ios 里面要在后面加.0f 再除以255 [bline setBackgroundColor:[UIColor colorWithRed:73.0 ...
- 解决Jquery向页面append新元素之后事件的绑定问题
/*经过用户技能标签增加样式*/ $(".s-edited").live("hover",function(){ $(this).toggleClass(&qu ...
- 牛客网-《剑指offer》-重建二叉树
题目:http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6 C++ /** * Definition for binary ...
- Python在线dlib库地址
一.地址 https://pypi.python.org/pypi/dlib/18.17.100
- 调用OpenCVSharp进行拍照
一.核心代码: using OpenCvSharp; using System; using System.Collections.Generic; using System.IO; using Sy ...
- 世纪互联提供的关于Powershell中将虚拟机加入备份保管库的方法
请您参考以下步骤进行操作,如有问题请与我们联系: 对一台ARM虚拟机(虚拟机名称:paularm08r21)进行备份(参考:https://www.azure.cn/documentation/art ...
- 机器学习-分类器-级联分类器训练(Train CascadeClassifier )
一.简介: adaboost分类器由级联分类器构成,"级联"是指最终的分类器是由几个简单分类器级联组成.在图像检测中,被检窗口依次通过每一级分类器,这样在前面几层的检测中大部分的候 ...
- C++ 第十一课 标准c内存函数
calloc() 分配一个二维储存空间 free() 释放已分配空间 malloc() 分配空间 realloc() 改变已分配空间的大小 calloc 语法: #include <st ...
- 原生Ajax使用教程
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6682564.html 浏览器端 一:创建XMLHttpRequest对象 所有现代浏览器均支 ...
- Linq to entity 执行多个字段排序的方法
可以连续使用:OrderBy,ThenBy 或者 OrderByDescending,ThenByDescending var data = db.User .Where(u => u.User ...