博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
夯实基础:关于线程的Callable和Future两个类解析
阅读量:4293 次
发布时间:2019-05-27

本文共 2334 字,大约阅读时间需要 7 分钟。

牛旦教育IT课堂 2019-02-28 14:45:59

译者:Greenster 校对:沈义扬

原文:http://www.javacodegeeks.com/2011/09/java-concurrency-tutorial-callable.html

概述

Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理。Thread类、Runnable接口和Java内存管理模型使得多线程编程简单直接。但正如之前提到过的,Thread类和Runnable接口都不允许声明检查型异常,也不能定义返回值。没有返回值这点稍微有点麻烦。

不能声明抛出检查型异常则更麻烦一些。public void run()方法契约意味着你必须捕获并处理检查型异常。即使你小心地保存了异常信息(译者注:在捕获异常时)以便稍后检查,但也不能保证这个类(译者注:Runnable对象)的所有使用者都读取异常信息。你也可以修改Runnable实现的getter,让它们都能抛出任务执行中的异常。但这种方法除了繁琐也不是十分安全可靠,你不能强迫使用者调用这些方法,程序员很可能会调用join()方法等待线程结束然后就不管了。

但是现在不用担心了,以上的问题终于在1.5及以后版中解决了。Callable接口和Future接口的引入以及他们对线程池的支持优雅地解决了这两个问题。

Callable

夯实基础:关于线程的Callable和Future两个类解析

 

Callable接口定义了方法public T call() throws Exception。我们可以在Callable实现中声明强类型的返回值,甚至是抛出异常。尽管在Executors类中已经有一些方法可以将Runnable对象转换为Callable对象(),你最好还是仔细复审现有的Runnable实现或Thread的子类。为什么还要这样做?主要是为了检查和清除因为Runnable无法抛出检查型异常而采用的变通方案。同时,你可能希望利用call()方法直接返回结果的能力,以省去读取值时的类型转换。

Future

夯实基础:关于线程的Callable和Future两个类解析

 

下面就将线程池和Callable接口相结合,看能发生怎样的效应。Future是从Java 1.5开始引入的接口,当你提交一个Callable对象给线程池时,将得到一个Future对象,并且它和你传入的Callable有相同的结果类型声明。这个对象取代了Java 1.5之前直接操作具体Thread实例的做法。过去你不得不用Thread.join()或者Thread.join(long millis)等待任务完成,而现在你可以像下面的例子那样做。

public class ServerAcceptingRequestsVerifier implements Callable { /** * @return Boolean.TRUE is server is accepting requests * Boolean.FALSE otherwise */ public Boolean call() throws Exception { Boolean isAcceptingRequests = null; ... ask server about taking requests here return isAcceptingRequests; }}public Boolean isServerTakingRequests(String server) throws UnresponsiveException, InterruptedException { ServerAcceptingRequestsVerifier acceptingRequestsVerifier = new ServerAcceptingRequestsVerifier(); Future future = THREAD_POOL.submit(acceptingRequestsVerifier); try { Boolean isAcceptingRequests = future.get(); //waits for the thread to complete, even if it hasn't started return isAcceptingRequests; } catch (ExecutionException e) { throw new UnresponsiveException(e.getCause()); }}

如果要限制等待任务结束的时间,也可以添加一个捕获TimeoutException的catch子句

try { Boolean isAcceptingRequests = future.get(5, TimeUnit.SECONDS); //this waits for 5 seconds, throwing TimeoutException if not done return isAcceptingRequests;} catch (TimeoutException e) { LOGGER.warn("Timed out waiting for server check thread." + "We'll try to interrupt it."); future.cancel(true); return Boolean.FALSE;} catch (ExecutionException e) { throw new UnresponsiveException(e.getCause());}

转载地址:http://fvzws.baihongyu.com/

你可能感兴趣的文章
jq使用教程02_安装的问题
查看>>
jq使用教程03_JQData说明书概要
查看>>
jq使用教程04_高校版教程
查看>>
jq使用教程05_ 新手也能用的安装版本,30秒点选即可安装完成,不需配置Python环境
查看>>
jq使用教程06_数据更新日志
查看>>
jq使用教程07_ JQData HTTP 接口正式上线
查看>>
jq使用教程08_基于估值波动周期的择时策略
查看>>
海龟交易法则14_掌控心魔
查看>>
海龟交易法则15_万事俱备
查看>>
海龟交易法则16_附原版海龟交易法则
查看>>
克罗谈投资策略01_期货交易中的墨菲法则
查看>>
克罗谈投资策略02_赢家和输家
查看>>
克罗谈投资策略03_你所期望的赌博方式
查看>>
克罗谈投资策略04_感觉与现实
查看>>
克罗谈投资策略05_涨势买入,跌势卖出
查看>>
通向财务自由之路01_导读
查看>>
通向财务自由之路02_成功的决定因素:你
查看>>
通向财务自由之路03_判断之偏好:掌握市场为何对多数人来说如此之难
查看>>
通向财务自由之路04_设定你的目标
查看>>
通向财务自由之路05_选择一个有效的理念
查看>>