Callable

在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。

不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。

Callable接口的定义如下:

public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}

与Runnable接口不同之处在于,call方法带有泛型返回值V。

Future模式

Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑

Futrure模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果。

在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程中可以做一些其他的事情。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /** 
 * @author wn: 
 * @version 上午16:53:57 
 * 类说明 
 */
public class ThreadCallTest {
  public static void main(String[]args){
ExecutorService executor=Executors.newCachedThreadPool();
Task task=new Task();
Future<Integer> result=executor.submit(task);
if (executor != null)
executor.shutdown();
  
try {
System.out.println("call result"+result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("over");
  
  }
} class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("3.开始 ....");
Thread.sleep(3000);
System.out.println("4.结束 ....");
return "xyz";
}
}

当Task启动后不影响主线程运行,result.get()会等待3秒后返回结果xyz

Future常用方法

V get() :获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。

V get(Long timeout , TimeUnit unit) :获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。

boolean isDone() :如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。 => result.isDone()

boolean isCanceller() :如果任务完成前被取消,则返回true。

boolean cancel(boolean mayInterruptRunning) :如果任务还没开始,执行cancel(...)方法将返回false;如果任务已经启动,执行cancel(true)方法将以中断执行此任务线程的方式来试图停止任务,如果停止成功,返回true;

当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;

当任务已经完成,执行cancel(...)方法将返回false。mayInterruptRunning参数表示是否中断执行中的线程。

实际上Future提供了3种功能:

  • (1)能够中断执行中的任务
  • (2)判断任务是否执行完成
  • (3)获取任务执行完成后的结果

个人博客 蜗牛

并发编程之Callable异步,Future模式的更多相关文章

  1. 并发编程 05—— Callable和Future

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  2. python并发编程之asyncio协程(三)

    协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...

  3. [转载]并发编程之Operation Queue和GCD

    并发编程之Operation Queue http://www.cocoachina.com/applenews/devnews/2013/1210/7506.html 随着移动设备的更新换代,移动设 ...

  4. Java并发编程之CAS

    CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...

  5. python并发编程之gevent协程(四)

    协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...

  6. python并发编程之multiprocessing进程(二)

    python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. 系列文章 python并发编程之threading线程(一) python并 ...

  7. Python进阶:并发编程之Futures

    区分并发和并行 并发(Concurrency). 由于Python 的解释器并不是线程安全的,为了解决由此带来的 race condition 等问题,Python 便引入了全局解释器锁,也就是同一时 ...

  8. Python核心技术与实战——十七|Python并发编程之Futures

    不论是哪一种语言,并发编程都是一项非常重要的技巧.比如我们上一章用的爬虫,就被广泛用在工业的各个领域.我们每天在各个网站.App上获取的新闻信息,很大一部分都是通过并发编程版本的爬虫获得的. 正确并合 ...

  9. 并发编程之J.U.C的第一篇

    并发编程之J.U.C AQS 原理 ReentrantLock 原理 1. 非公平锁实现原理 2)可重入原理 3. 可打断原理 5) 条件变量实现原理 3. 读写锁 3.1 ReentrantRead ...

随机推荐

  1. FormData实现文件上传

    我用到FormData传输的使用场景:vant UI组件里面 的图片上传这块,需要调用后台的图片上传接口,使用的是FormData方式上传的 https://www.cnblogs.com/hutuz ...

  2. OpenFOAM——运动和静止的同心圆柱之间的流动(库埃特流)

    本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL001: Flow Between Rotating and Stationary ...

  3. vue data不可以使用箭头函数的问题解析

    这篇文章主要介绍了vue data不可以使用箭头函数问题,本文通过源码解析给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 首先需要明确,a() {}和 b: () => {} ...

  4. Java-内存模型 synchronized 的内存语义

    synchronized 具有使每个线程依次排队操作共享变量的功能.这种同步机制效率很低,但 synchronized 是其它并发容器实现的基础. 一.锁对象及 synchronized 的使用 sy ...

  5. 运行OpenGL红宝书第9版源码时Visual Studio提示“无法启动程序...ALL_BUILD。拒绝访问“的问题的解决办法

    问题描述: OpenGL红宝书第9版源码采用CMake编译后,用相应的Visual Studio(如VS2012)打开“vermilion9.sln”解决方案,并运行时Visual Studio提示“ ...

  6. PHP系列 | ThinkPHP5数据库迁移工具 migration

    了解更多,请关注微信公众号 ThinkPHP5数据库迁移工具 migration 什么是Migration? migration用谷歌翻译是移民的意思,在PHP中我们将它理解为迁移,将Migratio ...

  7. 工具系列 | VScode VS Live Share 实时编码分享(和你的小伙伴一起写代码吧)

    Visual Studio Live Share能干啥? 分享任何语言,任何应用程序 无论您正在构建什么类型的应用程序,您正在编写什么语言,或者您的操作系统如何:在您需要协作时,Live Share会 ...

  8. Vintage、滚动率、迁移率的应用

    python信用评分卡建模(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_ca ...

  9. Android adb临时关闭Selinux

    在eng/userdebug版本中 使用getenforce 命令查询当前权限状态,如:adb shell getenforce 使用setenforce 命令进行设置:adb shell seten ...

  10. Qt请求http地址数据

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);; QNetworkRequest network_request; ...