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. Android笔记(七十四) 详解Intent

    我们最常使用Intent来实现Activity之间的转跳,最近做一个app用到从系统搜索图片的功能,使用到了intent的 setType 方法和 setAction 方法,网上搜索一番,发现实现转跳 ...

  2. Linux-普通用户切换为root身份

    Linux 下普通用户免密码切换 root 用户 具体步骤: 1)编辑 su 文件打开第四行注释 # vim /etc/pam.d/su 2)将用户添加到 wheel 组 # usermod -G w ...

  3. DB开发规范---初稿

    1 公共约定 1.1 存储引擎 默认统一使用InnoDB引擎 1.2 字符集设定 后续新建DB默认使用utf8mb4字符集,校对规则使用utf8mb4_general_bin. 历史DB多使用utf8 ...

  4. 洛谷 P2722 总分题解

    题目描述 我们可以从几个种类中选取竞赛的题目,这里的一个"种类"是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同的分数.你的任务是写一个程序来告诉USACO的 ...

  5. django项目中使用手机号登录

    本文使用聚合数据的短信接口,需要先获取到申请接口的appkey和模板id 项目目录下创建ubtils文件夹,定义返回随机验证码和调取短信接口的函数 function.py文件 import rando ...

  6. python通过json读写序列类型的数据文件

    import json class a: def writeReadJson(self): list2 =['] with open("test.txt",'w') as f: j ...

  7. danci4

    advantage 英 [əd'vɑːntɪdʒ] 美 [əd'væntɪdʒ] n. 优势:利益:有利条件 vi. 获利 vt. 有利于:使处于优势 lack 英 [læk] 美 [læk] vt. ...

  8. Json在序列化getter导致的问题

    Java中的Json序列化,不容忽视的getter 问题重现 public class AjaxJson { private boolean success; private String msg; ...

  9. 手机代理调试Charles Proxy和Fiddler

    一.Charles Proxy Charles是一个HTTP代理/HTTP监控/反向代理的工具. 使用它开发者可以查看设备的HTTP和SSL/HTTPS网络请求.返回.HTTP头信息 (cookies ...

  10. 代码中的mysql语法问题

    今天在代码中写了mysql的删除语句 String lpinsuredSQL=" delete from lpinsured a where a.insuredid='?InsuredID? ...