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的更多相关文章

  1. Java多线程:Callable,Future,FutureTask

    一.Future Future和Callable基本是成对出现的,Callable负责产生结果,Future负责获取结果.     1.Callable接口类似于Runnable,只是Runnable ...

  2. Java 并发编程——Callable+Future+FutureTask

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  3. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  4. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  5. java 并发runable,callable,future,futureTask

    转载自:http://www.cnblogs.com/dolphin0520/p/3949310.html package future_call; import java.util.concurre ...

  6. java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】

    Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...

  7. Java多线程知识-Callable和Future

    Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...

  8. java.util.concuttent Callable Future详解

    在传统的多线程实现方式中(继承Thread和实现Runnable)无法直接获取线程执行的返回结果,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 从 ...

  9. Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)

    java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)java多线程同步以及线程间通信详解&消费者生产者模式&死锁& ...

随机推荐

  1. 个人项目—WC

     一,Github地址:https://github.com/mushan520/WC.git 二.PSP表格: PSP2.1 Personal Software Process Stages 预估耗 ...

  2. trackingjs+websocket+百度人脸识别API,实现人脸签到

    在公司做了个年会的签到.抽奖系统.用java web做的,用公司的办公app扫二维码码即可签到,扫完码就在大屏幕上显示这个人的照片.之后领导让我改得高大上一点,用人脸识别来签到,就把扫二维码的步骤改成 ...

  3. vue2 手记

    vue2 手记 Vue文档:https://cn.vuejs.org/v2/api/#provide-inject Vue 生命周期:https://cn.vuejs.org/v2/guide/ins ...

  4. Python标准库-数字的处理函数(math模块)

    Python标准库-数字的处理函数(math模块) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. #!/usr/bin/env python #_*_conding:utf-8_* ...

  5. 二级数组省市表(二维数组json)

    <一省份.城市二级联动+vue搭架> a. template部分 <section class="edit__place"> <select v-mo ...

  6. Kotlin属性引用进阶与构造方法引用

    继续还是探讨Kotlin反射相关的知识点,说实话这块不是太好理解,待在实际工作中去对它进行实践慢慢来加深印象. 属性引用进阶: 在Kotlin中的反射其实是跟Java的反射有对应关系的,具体相关的定义 ...

  7. hexo利用SAE提高网页打开速度

    起因 之前一直觉得网页加载速度其实也还行,就是有两个图标加载的非常慢,经常是网页都出来了,那两个图标还是个方框,要等好久才出来.终于,好好研究了一番,发现那个图标是fontawesome里的,然后字体 ...

  8. MySQL数据的优化方案

    一.选取最使用的字段属性 mysql可以使用的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快,因此在创建表的时候,为了获得更好的性能,我们可以将表中的字段的宽度尽量设 ...

  9. 为什么需要 Redis 哨兵?

    在说哨兵之前,我们先说下主从复制,Redis 的主从复制模式,一旦主节点出现故障无法提供服务,需要人工介入手工将从节点调整为主节点,同时应用端还需要修改新的主节点地址,这种故障转移的方式对于很多应用场 ...

  10. nginx1.15.10配置使用非https访问返回403

    nginx版本号:nginx version: nginx/1.15.10 server { listen 443 default ssl; server_name app.test.com; if ...