异步获取线程执行结果,JDK中的Future、Netty中的Future和Promise对比

JDK中的Future和Netty中的Future、Promise的关系

三者源头追溯

        Netty中的Future与JDK中的Future同名,但是是两个不同的接口。Netty中的Future继承自JDK的Future,而Promise又对Netty中的Future进行了扩展。

  • JDK中的Future源自JUC并发包:

  • Netty中的Future源自Netty中的并发包:import io.netty.util.concurrent.Future; 并继承JUC中的Future。

  • Netty中的Promise继承自Netty中的Future,并且是一个接口,下面有一个实现类DefaultPromise<V>:

三者之间的区别和联系

  • jdk Future 只能同步等待任务结束(或成功、或失败)才能得到结果

  • netty Future 可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束

  • netty Promise 不仅有 netty Future 的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器

  • JDK和Netty中的Future并不是自己创建的,而是执行任务的线程执行结束后自己创建并且返回的。对于Future的创建权以及结果的设置均不是自己控制的,而是执行任务的线程控制的。Netty中的Promise可以提交者自己创建随后作为一个容器,供其他线程使用。

 代码演示

JDK中的Future

        代码编写:

        JDK中Future的获取依赖于线程池,首先创建线程池。

package com.example.code.netty.c4;

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;

@Slf4j
public class TestJDKFuture {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(2);
        // future的理解,就是线程之间通信的工具,一个线程中获取另一个线程的结果,需要另一个线程主动填充
        log.info("task begin ...");
        Future<Integer> future = service.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.info("task is running...");
                Thread.sleep(1000);
                // future是被动获取结果的,需要执行任务的线程向future中填充返回结果
                log.info("task is end ...");
                return 20;
            }
        });
        log.info("等待结果...");
        log.info("获取任务执行结果:{}", future.get());
    }
}

        结果展示:

        通过lombok中的@Slf4j注解,打印执行过程相关信息:主要关注①执行线程名称,②任务执行是都异步,获取结果是否是阻塞、同步。执行顺序如下所示:

         上述图片中的②和③执行顺序不能倒置,②属于主线程顺序执行,然而③属于新创建的线程中执行,线程的创建以及启动本身需要耗费一定的时间。

Netty中的Future

        Netty中的Future的获取依赖于EventLoop,需要首先创建EventLoop,等价于JDK中的Future的获取的线程池的创建。

        Netty中的Future对于结果的获取可以采用同步,也可也采用异步的方式。并且在异步获取结果时可以使用get()、getNow()两种方式获取。

  • get():获取任务结果,阻塞等待。
  • getNow():获取任务结果,非阻塞,还未产生结果时返回null。
package com.example.code.netty.c4;

import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

@Slf4j
public class TestNettyFuture {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        EventLoop eventLoop = eventLoopGroup.next();
        Future<Integer> future = eventLoop.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.info("task is running...");
                Thread.sleep(1000);
                // future是被动获取结果的,需要执行任务的线程向future中填充返回结果
                log.info("task is end ...");
                return 70;
            }
        });

        log.info("等待结果...");
        // 同步方式获取任务执行结果
//        log.info("获取任务执行结果:{}", future.get());
        // 异步方式获取执行结果
        future.addListener(new GenericFutureListener<Future<? super Integer>>() {
            @Override
            public void operationComplete(Future<? super Integer> future) throws Exception {
                // 异步获取执行结果既可以用future.get()阻塞方法,也可以用future.getNow()非阻塞方法。
                // 异步既然执行到了回调函数这一步,肯定已经能够获取到执行结果。
                log.info("获取任务执行结果:{}", future.getNow());
            }
        });
    }
}

        代码执行结果:【同步】

        代码执行结果:【异步】 

        同步方式下最终任务执行结果70的获取线程是当前main线程,而异步方式下最终执行结果70的获取是在nioEventLoopGroup中的某个线程也即任务线程本身中获取。 

Netty中的Promise

        Netty中的Promise继承自Netty中的Future,在继承Future相关功能的基础上,又实现了功能的增强。不仅可以在任务正确执行后设置执行结果,也可以在任务执行失败后设置执行结果。

  • setSuccess():设置成功结果。
  • setFailure():设置失败结果。

        代码编写:

package com.example.code.netty.c4;

import io.netty.channel.EventLoop;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.DefaultPromise;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;

@Slf4j
public class TestNettyPromise {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        EventLoop eventLoop = new NioEventLoopGroup().next();
        // 主动创建promise,结果容器
        DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
        log.info("task begin ...");
        new Thread(()->{
            log.info("task is running...");
            // 任意一个线程执行计算,计算完毕后向promise中填充结果。
            try {
//                int i = 1 / 0;
                Thread.sleep(1000);
                promise.setSuccess(10);
            } catch (Exception e) {
//                e.printStackTrace();
                promise.setFailure(e);
            }
            log.info("task end ...");
        }).start();
        log.info("等待结果...");
        log.info("获取任务执行结果:{}", promise.get());
    }
}

        代码执行结果:【同步】,异步执行结果不再演示,同Netty中的Future效果所示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/645733.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串

【LeetCode刷题】Day 7 题目1&#xff1a;209.长度最小的子数组思路分析&#xff1a;思路1&#xff1a;暴力枚举 O(N^2^)思路2&#xff1a;滑动窗口 O(N) 题目2&#xff1a;3. 无重复字符的最长子串题目分析&#xff1a;思想1&#xff1a;暴力枚举哈希表O(N^2^)思想2&#xff1…

鹏特资本进入中国市场具有以下一些优势

1. 带来资金&#xff1a;补充国内资金缺口&#xff0c;为企业发展和项目建设提供重要的资金支持。 2. 先进技术和管理经验&#xff1a;有助于推动技术创新和管理水平提升&#xff0c;促进产业升级和优化。 3. 促进竞争&#xff1a;激发国内市场活力&#xff0c;促使本土企业不…

Spring Cloud 项目中使用 Swagger

Spring Cloud 项目中使用 Swagger 关于方案的选择 在 Spring Cloud 项目中使用 Swagger 有以下 4 种方式&#xff1a; 方式一 &#xff1a;在网关处引入 Swagger &#xff0c;去聚合各个微服务的 Swagger。未来是访问网关的 Swagger 原生界面。 方式二 &#xff1a;在网关处引…

软件设计师笔记2

文章目录 软考知识点总结1. 计算机组成原理网络与信息安全数据结构与算法AOE网 编译原理操作系统软件设计软件测试数据库计算机软件产权其它 软考知识点总结 1. 计算机组成原理 cpu控制器&#xff0c;专门产生指令操作&#xff0c;送到计算机各个部位执行处理 DMA&#xff08…

ISCC2024个人挑战赛WP-WEB

&#xff08;非官方解&#xff0c;以下内容均互联网收集的信息和个人思路&#xff0c;仅供学习参考&#xff09; 还没想好名字的塔防游戏 GET /world.js HTTP/1.1 Host: 101.200.138.180:17345 Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,i…

LeetCode题练习与总结:二叉树的层序遍历Ⅱ--107

一、题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[…

嵌入式进阶——LED呼吸灯(PWM)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 PWM基础概念STC8H芯片PWMA应用PWM配置详解占空比 PWM基础概念 PWM全称是脉宽调制&#xff08;Pulse Width Modulation&#xff09…

C++笔试强训day33

目录 1.跳台阶扩展问题 2.包含不超过两种字符的最长子串 3.字符串的排列 1.跳台阶扩展问题 链接https://www.nowcoder.com/practice/953b74ca5c4d44bb91f39ac4ddea0fee?tpId230&tqId39750&ru/exam/oj 我是用动态规划解决的&#xff1a; #include <iostream>…

一文读懂:http免费升级https

背景&#xff1a; 随着现在全民网络安全意识的日益提升&#xff0c;各个网站需要实现的https数量也随之提升&#xff0c;那么如何将原本网站的http访问方式升级为https呢&#xff1f; 该内容为如何免费将网站的http访问升级为https访问 论https的加密逻辑&#xff1a; 步骤 …

【数据结构(邓俊辉)学习笔记】图01——图的表示与实现

文章目录 1. 概述1.1 邻接 关联1.2 无向 有向1.3 路径 环路 2. 邻接矩阵2.1 接口2.2 邻接矩阵 关联矩阵2.3 实例2.4 顶点和边2.5 邻接矩阵2.6 顶点静态操作2.7 边操作2.7 顶点动态操作2.8 综合评价 1. 概述 1.1 邻接 关联 相对于此前的线性以及半线性结构&#xff0c;图…

RAG概述(二):Advanced RAG 高级RAG

目录 概述 Advanced RAG Pre-Retrieval预检索 优化索引 增强数据粒度 粗粒度 细粒度 展开说说 优化索引 Chunk策略 Small2Big方法 元数据 引入假设性问题 对齐优化 混合检索 查询优化 查询扩展 查询转换 Post-Retrieval后检索 参考 概述 Native RAG&#…

Python并发编程学习记录

1、初识并发编程 1.1、串行&#xff0c;并行&#xff0c;并发 串行(serial)&#xff1a;一个cpu上按顺序完成多个任务&#xff1b; 并行(parallelism)&#xff1a;任务数小于或等于cup核数&#xff0c;多个任务是同时执行的&#xff1b; 并发(concurrency)&#xff1a;一个…

Linux之Nginx

1、Nginx 1.1、什么是Nginx Nginx最初由Igor Sysoev开发&#xff0c;最早在2004年公开发布。它被设计为一个轻量级、高性能的服务器&#xff0c;能够处理大量并发连接而不消耗过多的系统资源。Nginx的架构采用了事件驱动的方式&#xff0c;能够高效地处理请求。它的模块化设计使…

Redis 的持久化(真的好细)

前言 Redis 是一个内存数据库&#xff0c;把数据存储在内存中&#xff0c;而内存中的数据是不持久的&#xff0c;要想数据持久就得将数据存储到硬盘中&#xff0c;而 Redis 相比于 Mysql 这样的关系型数据库最大的优势就在于将数据存储在内存中从而效率更高&#xff0c;速度更快…

大数据智慧消防解决方案(24页PPT)

方案介绍&#xff1a; 大数据智慧消防解决方案是提升消防安全管理水平、保障人民群众生命财产安全的重要手段。通过集成物联网、云计算、大数据、人工智能等先进技术&#xff0c;构建集监测、预警、指挥、救援于一体的智慧消防系统&#xff0c;将为消防安全事业注入新的活力。…

单日收益1000+看了就会的项目,最新灵异短视频项目,简单好上手可放大操作

各位好友&#xff0c;佳哥在此与大伙儿聊聊一项神秘莫测的短视频项目。你或许会想&#xff0c;“又是一个视频创作项目&#xff1f;” 但别急&#xff0c;这个项目与众不同&#xff0c;日入千元不再是梦&#xff0c;而且它的易用性让人惊喜&#xff0c;无论你是初学者还是资深玩…

数据结构·一篇搞定队列!

hello&#xff0c;大家好啊&#xff0c;肖恩又拖更了&#xff0c;你们听我狡辩&#xff0c;前段时间有期中考试&#xff0c;so我就没什么时间写这个&#xff0c;在这给大家道个歉&#x1f62d;&#x1f62d;&#x1f62d; 我后面一定尽力不拖更 那么接下来&#xff0c;我们来看…

数字化转型必备:营销策划流程图,打造你的数字市场地图

制作营销策划流程图是一个系统化的过程&#xff0c;它可以帮助你清晰地规划和展示营销活动的各个阶段。 以下是制作营销策划流程图的步骤&#xff1a; 1.确定营销目标&#xff1a; 明确你的营销活动旨在实现的具体目标&#xff0c;比如提升品牌知名度、增加销售额、吸引新客…

【CCIE | 网络模拟器】部署 EVE-NG

目录 1. 环境准备2. 下载 EVE-NG 镜像3. 安装 EVE-NG 虚拟机3.1 创建 eve-ng 虚拟机3.2 选择存储3.3 定义虚拟机计算资源&#xff08;1&#xff09;开启CPU虚拟化功能&#xff08;2&#xff09;精简置备磁盘 3.4 检查虚拟机设置 4. 安装系统4.1 选择系统语言4.2 选择系统键盘类…

2024.05.25 第 131 场双周赛

Leetcode 第 131 场双周赛 求出出现两次数字的 XOR 值 [Leetcode 求出出现两次数字的 XOR 值](https://leetcode.cn/problems/find-the-xor-of-numbers-which-appear-twice/description/] 给你一个数组 nums &#xff0c;数组中的数字 要么 出现一次&#xff0c;要么 出现两次…