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应用与端口
			lsof -i:port --- 得到对应端口的应用pid PS -ef|grep pid --- 根据pid得到对应应用 
- mysql 设置查看字符集
			MySQL查看和修改字符集的方法 一.查看字符集 1.查看MYSQL数据库服务器和数据库字符集 方法一:show variables like '%character%';方法二:show var ... 
- C# 认识 接口
			一.什么是接口 C#接口中包含方法.属性.索引器和事件的声明,但常用的接口中一般就是方法和属性,然而接口中并没有方法的具体实现代码(不能提供任何成员实现),只有方法的返回类型和方法名.一个类实现了某个 ... 
- 【Mac】微信视频对方听不见你的声音
			解决方案: 1.打开系统设置 2.选择声音 3.输出选择第一个就可以 
- FriendlyCore overlayfs 挂载方式
			友善 friendlycore 挂载 overlayfs 过程: uboot 引导系统启动的时候加载 ramdisk.img 这个 cpio 格式的 initrd(虚拟文件系统). 注意: ramd ... 
- 【笔记】Reptile-一阶元学习算法
			目录 论文信息 Nichol A , Achiam J , Schulman J . On First-Order Meta-Learning Algorithms[J]. 2018. 一.摘要 本文 ... 
- AXURE RP EXTENSION For Chrome----解决办法
			出现这个问题是因为chrome://extensions/中没有安装扩展程序 解决办法: 步骤一:情景再现,打开某个html会出现如下页面,不停地提示你安装插件 步骤二:如果点击安装扩展程序,能够成功 ... 
- 编译heartbeat出现的问题
			如报 cc1: warnings being treated as errors pils.c:245: error: initialization fromincompatible pointer ... 
- 使用python的jira库操作jira的版本单和问题单链接
			操作JIRA的API来实现的. 但感觉比单纯操作API要简单一些. from jira import JIRA from django.conf import settings JIRA_URL = ... 
- Linux——配置maven
			前言 Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(De ... 
