java.util.java concurrent lock.Future.isDone是否有必要

您所在的位置: &
15.3.2 Callable与Future
15.3.2 Callable与Future
清华大学出版社
《Java JDK6学习笔记》第15章 线程(Thread),本章说明一些多线程的观念,并给出一些范例让您了解如何让程序具有多线程功能。本节为大家介绍的是Callable与Future。
15.3.2 Callable与Future
java.util.concurrent.Callable与java.util.concurrent.Future类可以协助您完成Future模式。Future模式在请求发生时,会先产生一个Future对象给发出请求的客户。它的作用类似于代理(Proxy)对象,而同时所代理的真正目标对象的生成是由一个新的线程持续进行。真正的目标对象生成之后,将之设置到Future之中,而当客户端真正需要目标对象时,目标对象也已经准备好,可以让客户提取使用。
关于Future模式的说明,可以参考:
Callable是一个接口,与Runnable类似,包含一个必须实现的方法,可以启动为让另一个线程来执行。不过Callable工作完成后,可以传回结果对象。Callable接口的定义如下:
public interface Callable&V& {V call() throws E}
例如,可以使用Callable完成某个费时的工作,工作结束后传回结果对象,例如求质数范例15.24:
范例15.24& PrimeCallable.java
package onlyfun.import java.util.ArrayLimport java.util.Limport java.util.concurrent.C
public class PrimeCallable implements Callable&int[]& {public PrimeCallable(int max) {&this.max =}public int[] call() throws Exception {int[] prime = new int[max+1]; List&Integer& list = new ArrayList&Integer&();
for(int i = 2; i &= i++) prime[i] = 1;
for(int i = 2; i*i &= i++) { // 这里可以改进 if(prime[i] == 1) { for(int j = 2*i; j &= j++) { if(j % i == 0) prime[j] = 0; } } }
for(int i = 2; i & i++) { if(prime[i] == 1) { list.add(i); } }int[] p = new int[list.size()];for(int i = 0; i & p. i++) {&p[i] = list.get(i).intValue();}}&}
程序中的求质数方法是很简单的,但效率不好,这里只是为了示范方便,才使用简单的求质数方法,要更有效率地求质数,可以参考Eratosthenes筛选求质数:
假设现在求质数的需求是在启动PrimeCallable后的几秒之后,则可以使用Future来获得Callable执行的结果,从而在未来的时间点获得结果,例如范例15.25:
范例15.25& FutureDemo.java
package onlyfun.import java.util.concurrent.Cimport java.util.concurrent.ExecutionEimport java.util.concurrent.FutureTpublic class FutureDemo {public static void main(String[] args) {Callable&int[]& primeCallable = new PrimeCallable(1000);FutureTask&int[]& primeTask = new FutureTask&int[]&(primeCallable);Thread t = new Thread(primeTask);t.start();try {// 假设现在做其他事情Thread.sleep(5000);// 回来看看质数找好了吗if(primeTask.isDone()) {int[] primes = primeTask.get();for(int prime : primes) {System.out.print(prime + " ");}System.out.println();}} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}&}}java.util.concurrent.FutureTask是一个代理,真正执行找质数功能的是Callable对象。使用另一个线程启动FutureTask,之后就可以做其他的事了。等到某个时间点,用isDone()观察任务是否完成,如果完成了,就可以获得结果。一个执行结果如下,显示所有找到的质数:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641643 647 653 659 661 673 677 683 691 701 709 719727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997用户可能需要快速翻页浏览文件,但在浏览到有图片的页数时,由于图片文件很大,导致图片加载较慢,造成用户浏览文件时会有停顿的现象。因此希望在文件开启之后,仍有一个后台作业持续加载图片。这样,用户在快速浏览页面时,所造成的停顿可以获得改善,从而可以考虑使用这里所介绍的功能。【责任编辑: TEL:(010)】&&&&&&
关于&&&&&&&&的更多文章
TIOBE编程语言排行榜Java以4.5%的差距遥遥领先于第二名,以后使
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
讲师: 39人学习过讲师: 7人学习过讲师: 10人学习过
本书将帮助你理解和使用PostgreSQL这一开源数据库系统
本书由业界最先进的动画库Velocity.js的作者所著,书
本书是一本全面的C++教程,介绍C++编程知识及问题解决
本书是根据全国计算机技术与软件专业技术资格(水平)考试的“计算机网络管理员考试大纲”所要求的考试范围而编写的辅导用书。全
51CTO旗下网站FutureTask是一个可取消的异步计算(A cancellable asynchronous computation.)
FutureTask可处于等待运行、正在运行和运行完成这3种状态,运行完成包括所有可能的结束方式:正常结束、由于取消而结束和异常运行结束,FutureTask进入运行完成状态后,将永远处于该状态
示例一:FutureTask的简单示例(调用FutureTask的run方法使其开始运行,也可将其封装至Thread中通过调用Thread的start方法间接调用FutureTask的run方法)
import java.util.concurrent.C
import java.util.concurrent.FutureT
public final class MyFutureTask&V& extends FutureTask&V& {
public MyFutureTask(Callable&V& callable) {
super(callable);
//当任务进入运行结束状态,无论是正常结束、取消任务还是异常结束
//都将会调用该方法
protected void done() {
if(this.isDone()){
System.out.println(&MyFutureTask is over!&);
import java.util.concurrent.C
import java.util.concurrent.ExecutionE
public class Task{
private MyFutureTask&Integer& ft = new MyFutureTask&Integer&(
new Callable&Integer&() {
public Integer call() throws Exception {
return new Integer(0);
private Thread t = new Thread(ft);
public void run(){
t.start();
public Integer get() throws InterruptedException, ExecutionException{
//get()方法的运行方式取决于任务的状态
//如果任务已经完成,则直接返回结果
//如果任务正在运行中,则阻塞直到任务完成
return ft.get();
public boolean cancel(){
//尝试取消任务,如果任务处于运行结束状态或由于其它某些原因
//无法取消,则尝试失败
return ft.cancel(true);
public boolean isDone(){
return ft.isDone();
public static void main(String[] args)
throws InterruptedException, ExecutionException {
Task task = new Task();
//如果运行任务时任务处于运行结束状态则会报线程状态异常:
//java.lang.IllegalThreadStateException
if(!task.isDone()){
task.run();
Thread.sleep(1000);
//此时任务已经完成,故取消失败
System.out.println(task.cancel());
System.out.println(&result:& + task.get());
运行结果如下:
MyFutureTask is over!
示例二:使用FutureTask实现的高效结果缓存
本文已收录于以下专栏:
相关文章推荐
通过前面几篇的学习,我们知道创建线程的方式有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,那如果我们想要获取返回结...
第三方统计工具Crashlytics
人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..
java.util.concurrent
Class FutureTask
java.lang.Object
java.util.concurrent.FutureTask
...
 | New 
| Browse 
| Search 
| Reports 
| Help 
| Log In
First Last&#16...
Caused by: java.lang.IllegalArgumentException: The servlets named [cui.ys.request.ResponseDemo6] and...
jsp开发web后台时配置出错问题
昨晚12:00运行自动化测试脚本时遇到了java.util.concurrent.RejectedExecutionException这个异常,从异常名称里很容易分析出是提交的任务被线程池拒绝了...
pthread_t的定义以及初始化。
/dolphin0520/p/3681042.html
他的最新文章
讲师:董西成
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Java 9的14个新特性总结
Java 9的14个新特性总结
Java 9 包含了丰富的特性集。虽然Java 9没有新的语言概念,但是有开发者感兴趣的新的API和诊断命令。
我们将快速的,着重的浏览其中的几个新特性;
模块化系统–Jigsaw 项目
模块化是一个很通用的概念。在软件中,模块化可以运用到编写和实现一个程序和计算系统,他们都是作为独立的模块,而不是作为一个单一的和完整的设计。
Java 9中主要的变化是已经实现的模块化系统。模块化的引入使得JDK可以在更小的设备中使用。采用模块化系统的应用程序只需要这些应用程序所需的那部分JDK模块,而非是整个JDK框架了。模块化系统也可以将公共的类封装到一个模块中。因此一个封装在模块中的定义为public的类不能再任何地方使用,除非一个模块显式的定义了这个模块。由于Java 9的这个变化,Java内部的API(例如com.sun.*)默认情况下是不能使用的。
简而言之,所有的模块将需要在所谓的module-info.java文件中进行描述,这个文件是位于Java代码结构的顶层。
如果你想学习Java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面有大量的学习资料可以下载。
module me.aboullaite.java9.modules.car {
requires me.aboullaite.java9.modules.//依赖的模块
exports me.aboullaite.java9.modules.car.//在模块中导出包
我们的模块car(汽车)需要依赖+模块engine(引擎)和需要导出handling(操纵)包。
需要更多深入的例子可以查看OpenJDK中项目Jigsaw:。
JShell–Java 9 REPL
你可能问:“REPL是什么”?REPL是一种快速运行语句的命令行工具。
在Java中,如果你想执行一个简单的语句,我们要么创建一个带main方法的类,要么创建一个可以执行的Test类。当你正在启动Java程序的时候,如果你想执行某些语句并且想立刻看见执行结果,上面的做法看起来不是那么有用了。
JShell试图去解决这个问题。Java开发者可以利用JShell在没有创建类的情况下直接声明变量,计算表达式,执行语句。JShell也可以从文件中加载语句或者将语句保存到文件中。并且JShell也可以是tab键进行自动补全的特性。
集合工厂方法
在Java 9之前,Java只能利用一些实用方法(例如:Collections.unmodifiableCollection(Collection&? extends T& c))创建一个不可修改视图的集合。例如,我们可以在Java 8中使用一条如下所示的语句,创建一个Collection的不可修改的视图。虽然这是最简单的创建方式,但是看起来很糟糕!不是吗?
Map&String, String& immutableMap =
Collections.unmodifiableMap(
new HashMap&String, String&() {{
put("key1", "Value1");
put("key2", "Value2");
put("key3", "Value3");
现在,Java 9引入了一些有用的工厂方法来创建不可修改的集合。我们现在在Java 9中创建不可修改的Map集合,如下所示。
Map&String, String& immutableMap = Map.of("key1", "Value1", "key2", "Value2","key3", "Value3");
下面是工厂方法的例子:
// empty immutable collections 不可修改的空集合
List&String& emptyImmutableList = List.of();
Set&String& emptyImmutableSet = Set.of();
Map emptyImmutableMap = Map.of();
// immutable collections 不可修改的集合
List&String& immutableList = List.of("one", "two");
Set&String& immutableSet = Set.of("value1", "value2");
Map&String, String& immutableMap = Map.of("key1", "Value1", "key2", "Value2", "key3", "Value3");
接口中的私有方法
Java 8的接口引入了默认方法和静态方法。虽然Java 8首次计划实现接口的私有方法,却是在Java 9中实现。默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。
interface InterfaceWithPrivateMethods {
private static String staticPrivate() {
return "static private";
private String instancePrivate() {
return "instance private";
default void check() {
String result = staticPrivate();
InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {
// anonymous class 匿名类
result = pvt.instancePrivate();
JDK9中的Flow API对应响应式流规范,响应式流规范是一种事实标准。包含了一组最小接口集合,这组接口能捕获核心的异步发布与订阅。希望在未来第三方能够实现这些接口,并且能共享其方式。
java.util.concurrent.Flow包含以下4个接口:
* (处理器)
* (发布者)
* (订阅者)
* (订阅管理器)
这些接口都支持响应式流发布-订阅框架。Java 9也提供了实用类SubmissionPublisher。一个发布者产生一个或多个物品,这些物品由一个或多个消费者消耗。并且订阅者由订阅管理器管理。订阅管理器连接发布者和订阅者。
多分辨率图像API–JEP 251
目标是定义多分辨率图像API,这样开发者就能很容易的操作和展示不同分辨率的图像了。
这个新的API定义在java.awt.image包中,这个API能给我们带来如下的帮助:
* 将不同分辨率的图像封装到一张(多分辨率的)图像中,作为它的变体。
* 获取这个图像的所有变体。
* 获取特定分辨率的图像变体–表示一张已知分辨率单位为DPI的特定尺寸大小的逻辑图像,并且这张图像是最佳的变体。
基于当前屏幕分辨率大小和运用的图像转换算法,java.awt.Graphics类可以从接口MultiResolutionImage获取所需的变体。java.awt.image.AbstractMultiResolutionImage类提供了ava.awt.image.AbstractMultiResolutionImage 默认实现。AbstractMultiResolutionImage的基础实现是java.awt.image.BaseMultiResolutionImage。
进程API的改进
迄今为止,通过Java来控制和管理操作系统的进程的能力有限。例如,为了做一些简单的事情,像获取进程的PID,你要么需要访问本地代码,要么使用某种临时解决方案。不仅如此,每个(系统)平台需要一个不同实现来确保你能获得正确的结果。
在Java 9中,期望代码能获取Linux PID,现在是如下方式:
public static void main(String[] args) throws Exception
Process proc = Runtime.getRuntime().exec(new String[]{ "/bin/sh", "-c", "echo $PPID" });
if (proc.waitFor() == 0)
InputStream in = proc.getInputStream();
int available = in.available();
byte[] outputBytes = new byte[available];
in.read(outputBytes);
String pid = new String(outputBytes);
System.out.println("Your pid is " + pid);
你可以变换如下的方式(同样支持所有的操作系统):
System.out.println("Your pid is " + Process.getCurrentPid());
Try-With-Resources
在Java 7中,try-with-resouces语法要求为每一个资源声明一个新的变量,而且这些资源由try-with-resources语句进行管理。
在就Java 9中,有另外一个改进:如果一个资源被final或者等效于final变量引用,则在不需要声明一个新的变量的情况下,try-with-resources就可以管理这个资源。
MyAutoCloseable mac = new MyAutoCloseable();
try (mac) {
// do some stuff with mac
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
// do some stuff with finalCloseable
钻石(diamond)操作符范围的延伸
Java 7给出的钻石操作符使我们编写代码更简单了。在下面的例子中,你可以看见Java 7中List(列表)的可读性更强了,并且使代码更加的简洁了。
List&String& preJava7 = new ArrayList&String&();//java 7 之前的写法
List&String& java7 = new ArrayList&&();//java 7 之后的写法
但是Java 7中钻石操作符不允许在匿名类上使用。但在Java 9中改善了这一情况,允许钻石操作符在匿名类上使用。下面的例子只有在Java 9中才能通过编译。
List&String& list = new ArrayList&&(){ };
增强的注释Deprecated
注释@Deprecated可以标记Java API。注释@Deprecated有很多种含义,例如它可以表示在不远的将来的某个时间,被标记的API将会被移除。它也可以表示这个API已经被破坏了,并不应该再被使用。它还有其它很多含义。为了提供更多有关@Deprecated的信息,@Deprecated添加了forRemoval元素和since元素。
Java SE 9 中也提供了扫描jar文件的工具jdeprscan。这款工具也可以扫描一个聚合类,这个类使用了Java SE中的已废弃的API元素。 这个工具将会对使用已经编译好的库的应用程序有帮助,这样使用者就不知道这个已经编译好的库中使用了那些已废弃的API。
统一的JVM日志
如今,我们很难知道导致JVM性能问题和导致JVM崩溃的根本原因。解决这个问题的一个方法是对所有的JVM组件引入一个单一的系统,这些JVM组件支持细粒度的和易配置的。目前,不同的JVM组件对于日志使用的是不同的机制和规则,这使得JVM难以进行调试。
注释SafeVarargs范围的延伸
直到Java 8,@SafeVarargs才能在静态方法、final方法和构造器上使用。但是这些方法或者构造器是不能被覆盖的。这些方法中缺少另一个不能被覆盖的方法,这个方法就是私有方法。Java 9可以将@SafeVarargs添加到私有方法上。下面的例子在Java 9中是正确的,但是在Java 8中就会抛出编译时错误:注释@SafeVarargs不能在非final的实例方法iAmSafeVaragrsMethod上使用。
@SafeVarargs
private void iAmSafeVaragrsMethod(String... varagrgs)
for (String each: varagrgs) {
System.out.println(each);
HTTP 2 客户端
Java 9采用了全新的HTTP客户端API,这些API支持HTTP/2协议和WebSocket协议,并且替换了遗留的HTTPURLConnectionAPI。这些改变并不应该在Java 9中完成。这些API可以从Incubator(孵化器)模块中获取。因此在默认情况下,这个模块是不能根据classpath获取的,需要使用--add-modules命令选项配置这个模块,将这个模块添加到classpath中。
我们创建一个HTTPRequest请求和获取异步的响应:
URI testPageURI = new URI("http://127.0.0.1:8080/testPage");
CompletableFuture&HttpResponse& nonBlockingResponse =
HttpRequest
.create(testPageURI)
.GET().responseAsync();
int tries = 0;
while(!nonBlockingResponse.isDone() && tries++ & 5) { Thread.sleep(5); } if (nonBlockingResponse.isDone()) { HttpResponse response = nonBlockingResponse.get(); System.out.println("status code : " + response.statusCode() + " --& " +
response.body(HttpResponse.asString()));
nonBlockingResponse.cancel(true);
System.out.println("Cancelling, could not get response");
HTML5风格的Java帮助文档
Java 8以及之前的版本生成的Java帮助文档是在HTML 4中,而HTML 4已经是很久的标准了。在Java 9中,javadoc命令行中选项部分添加了输出选项,这个选项的值要么是HTML 4,要么是HTML 5。现在HTML 4是默认的输出标记语言,但是在之后发布的JDK中,HTML 5将会是默认的输出标记语言。Java帮助文档还是由三个框架组成的结构构成,这是不会变的,并且以HTML 5输出的Java帮助文档也保持相同的结构。
更多的特性
* 保留下划线字符。变量不能被命名为_;
* 废弃Applet API;
* javac不再支持Java1.4以及之前的版本;
* 废弃Java浏览器插件;
* 栈遍历API–栈遍历API能过滤和迟访问在堆栈跟踪中的信息。
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】浅析混合云和跨地域网络构建实践,分享高性能负载均衡设计,9月21日阿里云专家和你说说网络那些事儿,足不出户看直播,赶紧预约吧!&&
API 网关(API Gateway),提供高性能、高可用的 API 托管服务,帮助用户对外开放其部署在 ECS...
以阿里云成熟的商业化云服务为基础,为游戏开发者、运营企业提供专属集群、尊享VIP服务、专项扶持基金、及多场景多类...
HTTPDNS是面向移动开发者推出的一款域名解析产品,具有域名防劫持、精准调度的特性。
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
MaxCompute75折抢购
Loading...}

我要回帖

更多关于 java concurrent 源码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信