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. sql server快捷键添加

    工具--选项--键盘 sp_table_column_info p_helpindex sp_sql

  2. springboot+vue2.x 解决session跨域失效问题

    服务端SpringBoot2.x   :localhost:8082 前端Vue2.x                 :localhost:81 前后端的端口号不同,为跨域,导致前端访问后端时,每次 ...

  3. windows10 进入BIOS

    windows10开机进入不了BIOS 原因 上网查了电脑固件所应该有的进入键,什么F1.F2.F12.Delete以及什么要配置Fn+F1...等等方法就是开机进入不了BIOS. 解决办法 最后发现 ...

  4. Django设置应用名与模型名为中文

    修改polls包里面的apps.py: from django.apps import AppConfig class PollsConfig(AppConfig): name = 'polls' v ...

  5. 项目Alpha冲刺(团队)-第九天冲刺

    格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Alpha冲刺(团队) 团队名称:为了交项目干杯 作业目标:描述第九天冲刺的项目进展.问题困难.心得体会 队员姓名与学号 队员学号 ...

  6. 自动生成百度小程序sitemap.txt文件路径

    因为业务需要,需要在目前项目上开发一个百度小程序,百度智能小程序上线了,但是内容每天得推送,不可能一个小程序路径一个推送吧,因为小程序路径和项目路径不一致. 因为项目是用ThinkPHP开发的,在此附 ...

  7. T-sql 遍历结果集

    DECLARE @TAB TABLE( [科室编号] [varchar](50) NULL, [科室编码] [varchar](50) NULL, [科室名称] [varchar](50) NULL, ...

  8. 9、Python复杂数据类型(list、tuple、set、dict)

    一.列表(list):[a1,a2],可变数据类型 1.序列: 序列是基类类型,序列扩展类型包括:字符串.元组和列表 序列都可以进行的操作包括索引,切片,加,乘,检查成员. 此外,Python已经内置 ...

  9. JAVA项目部署到云服务器

    转自:(此处更详细)http://blog.csdn.net/gulu_gulu_jp/article/details/50994003 一.前言 前面我们已经尝过了在云服务器上部署代码的甜头了,现在 ...

  10. pycharm激活2018(终极解决办法)

    1.将“0.0.0.0 account.jetbrains.com”中的内容添加到hosts文件中,hosts路径为:C:\Windows\System32\drivers\etc 2.打开http: ...