Java多线程的Callable, Future, FutureCallback
Callable可以看成是一个增强版的Runnable, 带返回结果, 需要通过Future或者FutureTask来提交任务或运行线程, 然后通过Future/FutureTask的get方法得到返回结果.
Callable在子线程中运行, 在主线程中异步得到执行结果(get()方法是阻塞的), 或者检查是否已取消, 是否已完成(检查取消和完成的方法是非阻塞的)
通过Thread子线程启动
这种方式, 需要创建一个FutureTask对象, 再用这个FutureTask对象创建一个Thread来运行. 后续操作都通过FutureTask进行.
public class DemoCallableFuture {
public static void main(String[] args) {
FutureTask<String> task = new FutureTask<>(()->{
System.out.println("task start");
Thread.sleep(1000);
System.out.println("task done");
return "task get";
});
new Thread(task).start();
FutureTask<String> task2 = new FutureTask<>(()->{
System.out.println("task2 start");
Thread.sleep(1000);
System.out.println("task2 done");
return "task2 get";
});
new Thread(task2).start();
if (task.isCancelled()) {
System.out.println("task cancelled yes");
} else {
System.out.println("task cancelled no");
}
if (task.isDone()) {
System.out.println("task done yes");
} else {
System.out.println("task done no");
}
try {
System.out.println(task.get());
} catch (InterruptedException|ExecutionException e) {
e.printStackTrace();
}
if (task2.isCancelled()) {
System.out.println("task2 cancelled yes");
} else {
System.out.println("task2 cancelled no");
}
if (task2.isDone()) {
System.out.println("task2 done yes");
} else {
System.out.println("task2 done no");
}
try {
System.out.println(task2.get());
} catch (InterruptedException|ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果
task start
task cancelled no
task done no
task2 start
task2 done
task done
task get
task2 cancelled no
task2 done yes
task2 get
通过ExecutorService线程池启动
这种方式, 通过线程池submit一个Callable对象, 就会得到一个Future对象, 根据这个Future对象做后续操作
public class DemoCallableFuture2 {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(4);
Future<String> future = service.submit(()->{
System.out.println("task start");
Thread.sleep(1000);
System.out.println("task done");
return "task get";
});
if (future.isCancelled()) {
System.out.println("task cancelled yes");
} else {
System.out.println("task cancelled no");
}
if (future.isDone()) {
System.out.println("task done yes");
} else {
System.out.println("task done no");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (future.isCancelled()) {
System.out.println("task cancelled yes");
} else {
System.out.println("task cancelled no");
}
if (future.isDone()) {
System.out.println("task done yes");
} else {
System.out.println("task done no");
}
try {
System.out.println(future.get());
} catch (InterruptedException|ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果
task cancelled no
task done no
task start
task cancelled no
task done no
task done
task get
.
FutureCallback
FutureCallback是Google Guava中的一个类, 解决的是Future中get阻塞的问题, 让全过程异步. 需要使用ListeningExecutorService的线程池提交.
代码例子
public class DemoFutureCallback {
public static void main(String[] args) {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
for (int i = 0; i < 5; i++) {
int j = i;
ListenableFuture<String> future = service.submit(()->{
System.out.println("task start");
Thread.sleep(1000);
System.out.println("task done");
return "task return " + j;
});
Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String s) {
System.out.println("callback success: " + s);
}
@Override
public void onFailure(Throwable throwable) {
throwable.printStackTrace();
}
});
}
System.out.println("thread ongoing");
service.shutdown();
}
}
运行结果
task start
task start
task start
thread ongoing
task start
task start
task done
callback success: task return 0
task done
callback success: task return 1
task done
callback success: task return 3
task done
callback success: task return 4
task done
callback success: task return 2 Process finished with exit code 0
Java多线程的Callable, Future, FutureCallback的更多相关文章
- Java多线程:Callable,Future,FutureTask
一.Future Future和Callable基本是成对出现的,Callable负责产生结果,Future负责获取结果. 1.Callable接口类似于Runnable,只是Runnable ...
- 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 并发runable,callable,future,futureTask
转载自:http://www.cnblogs.com/dolphin0520/p/3949310.html package future_call; import java.util.concurre ...
- java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】
Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...
- Java多线程知识-Callable和Future
Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...
- java.util.concuttent Callable Future详解
在传统的多线程实现方式中(继承Thread和实现Runnable)无法直接获取线程执行的返回结果,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 从 ...
- Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)
java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)java多线程同步以及线程间通信详解&消费者生产者模式&死锁& ...
随机推荐
- Linux--基本目录
特点 系统版本:CentOS 6.5 Linux目录:一切从根开始 Linux下面的设备(磁盘)不挂载的话没有办法使用,使用设备必须有一个入口,挂载点实质就是一个目录. 目录结构及含义 目录 说明 b ...
- QQ推广工具
目前比较简单易用的QQ推广工具有:一键加群.在线聊天 一.一键加群 1.官网链接 http://qun.qq.com/join.html 2.使用 1登录自己的QQ 2创建一个想要作为推广的群 3选择 ...
- tree - 列出树状目录结构
tree - list contents of directories in a tree-like format. 树状显示目录结构 常用格式: tree [option] [directory] ...
- SVN无法检出项目
情况说明: SVN的管理员给我一个项目的检出权限,我用浏览器可以访问,TortoiseSVN无法检出,提示没有访问URL的权限,不能检出. SVN管理员交流别人可以使用,我用同事的电脑,使用我的账号检 ...
- Electrification Plan 最小生成树(prim+krusl+堆优化prim)
题目 题意: 无向图,给n个城市,n*n条边,每条边都有一个权值 代表修路的代价,其中有k个点有发电站,给出这k个点的编号,要每一个城市都连到发电站,问最小的修路代价. 思路: prim:把发电站之间 ...
- springboot无法识别配置文件级解决办法
eclipse中右键项目bulid path 之后找到 后点击完成后点击运用 修改完成
- Python开发应用之-SQL 建索引的几大原则
SQL 建索引的几大原则: 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>.<.between.like)就停止匹配,比如a = 1 and b = ...
- MSDS 596 Homework
MSDS 596 Homework 10 Due November 28 2017Notes. The lowest grade among all eleven homework will be d ...
- Python 生成 JWT(json web token) 及 解析方式
一.关于 jwt 的原理及概念可以自行在网络上搜索了解一下,这里推荐一篇写的比较好的博客 深入了解Json Web Token之概念篇 另附 JWT 的官方文档: https://jwt.io/int ...
- PHP——数组根据某一键值合并
前言 其实要实现很简单直接foreach,再根据PHP中数组的特性就可以轻松实现. 步骤 这是源数据的格式 $info = [ [ "gname" => "特别关心 ...