异步获取线程执行结果,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>() {@Overridepublic 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>() {@Overridepublic 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>>() {@Overridepublic 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效果所示。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电商API接口(api商品数据)【电商商品实时数据采集API接口】

众多品牌选择电商API实时数据采集接口进行采购&#xff0c;主要是出于以下几个重要原因&#xff1a; 第一&#xff0c;高效便捷。比价工具通过自动化的方式获取价格信息&#xff0c;避免了繁琐的人工操作&#xff0c;大大节省了时间和精力。 第二&#xff0c;精准比较。API比价…

如何使用ssh将vscode 连接到服务器上,手把手指导

一、背景 我们在开发时&#xff0c;经常是window上安装一个vscode编辑器&#xff0c;去连接一个虚拟机上的linux&#xff0c;这里常用的是SSH协议&#xff0c;了解其中的操作非常必要。 二、SSH协议 SSH&#xff08;Secure Shell&#xff09;是一种安全协议&#xff0c;用于…

C#屏蔽基类成员

可以用与积累成员名称相同的成员来屏蔽 要让编译器知道你在故意屏蔽继承的成员&#xff0c;可以用new修饰符。否则程序可以成功编译&#xff0c;但是编译器会警告你隐藏了一个继承的成员 using System;class someClass {public string F1 "Someclass F1";public v…

YOLOv10 | 手把手教你利用yolov10训练自己数据集(含环境搭建 + 参数解析 + 数据集查找 + 模型训练、推理、导出)

一、前言 本文内含YOLOv10网络结构图 各个创新模块手撕结构图 训练教程 推理教程 参数解析 环境搭建 数据集获取等一些有关YOLOv10的内容&#xff01; 目录 一、 前言 二、整体网络结构图 三、空间-通道分离下采样 3.1 SCDown介绍 3.2 C2fUIB介绍 3.3 PSA介绍 …

微服务下认证授权框架的探讨

前言 市面上关于认证授权的框架已经比较丰富了,大都是关于单体应用的认证授权,在分布式架构下,使用比较多的方案是--<应用网关>,网关里集中认证,将认证通过的请求再转发给代理的服务,这种中心化的方式并不适用于微服务,这里讨论另一种方案--<认证中心>,利用jwt去中…

【数据库基础-mysql详解之索引的魅力(N叉树)】

索引的魅力目录 &#x1f308;索引的概念&#x1f308;使用场景&#x1f308;索引的使用&#x1f31e;&#x1f31e;&#x1f31e;查看MySQL中的默认索引&#x1f31e;&#x1f31e;&#x1f31e;创建索引&#x1f31e;&#x1f31e;&#x1f31e;删除索引 站在索引背后的那个男…

sheng的学习笔记-docker部署Greenplum

目录 docker安装gp数据库 mac版本 搭建gp数据库 连接数据库 windows版本 搭建gp数据库 连接数据库 docker安装gp数据库 mac版本 搭建gp数据库 打开终端&#xff0c;输入代码&#xff0c;查看版本 ocker search greenplum docker pull projectairws/greenplum docker…

Virtual Box安装Ubuntu及设置

Virtual Box安装Ubuntu及设置 本文包含以下内容&#xff1a; 使用Virtual Box安装Ubuntu Desktop。设置虚拟机中的Ubuntu&#xff0c;使之可访问互联网并可通过SSH访问。 Ubuntu Desktop下载 从官网下载&#xff0c;地址为&#xff1a;Download Ubuntu Desktop | Ubuntu U…

HTTP交互导致ECONNABORTED的原因之一

背景&#xff1a; 本次记录的&#xff0c;是一次使用HTTP交互过程中遇到的问题&#xff0c;问题不大&#xff0c;就是给题目上这个报错补充一种可能的解决方案。 程序大致流程&#xff1a; 1. 设备向服务器A请求信息 2. 拿到回复记录下回复内容中的数据包下载地址等信息 3…

games 101 作业4

games 101 作业4 题目题解作业答案 题目 Bzier 曲线是一种用于计算机图形学的参数曲线。在本次作业中&#xff0c;你需要实 现 de Casteljau 算法来绘制由 4 个控制点表示的 Bzier 曲线 (当你正确实现该 算法时&#xff0c;你可以支持绘制由更多点来控制的 Bzier 曲线)。 你需…

IntelliJ IDEA实用插件:轻松生成时序图和类图

IntelliJ IDEA生成时序图、类图 一、SequenceDiagram1.1 插件安装1.2 插件设置1.3 生成时序图 二、PlantUML Integration2.1 插件安装2.2 插件设置2.3 生成类图 在软件建模课程的学习中&#xff0c;大家学习过多种图形表示方法&#xff0c;这些图形主要用于软件产品设计。在传统…

C++实现定长内存池

项目介绍 本项目实现的是一个高并发的内存池&#xff0c;它的原型是Google的一个开源项目tcmalloc&#xff0c;tcmalloc全称Thread-Caching Malloc&#xff0c;即线程缓存的malloc&#xff0c;实现了高效的多线程内存管理&#xff0c;用于替换系统的内存分配相关函数malloc和fr…

Java面向对象知识总结+思维导图

&#x1f516;面向对象 &#x1f4d6; Java作为面向对象的编程语言&#xff0c;我们首先必须要了解类和对象的概念&#xff0c;本章的所有内容和知识都是围绕类和对象展开的&#xff01; ▐ 思维导图1 ▐ 类和对象的概念 • 简单来说&#xff0c;类就是对具有相同特征的一类事…

【Spring】认识 IoC 容器和 Servlet 容器

认识 IoC 容器和 Servlet 容器 1.认识容器1.1 IoC 容器1.2 loC 的实现方法1.2.1 依赖注入1.2.2 依赖查找 1.3 认识 Servlet 容器 2.用 IoC 管理 Bean2.1 创建一个 Bean2.2 编写 User 的配置类2.3 编写测试类 3.用 Servlet 处理请求3.1 注册 Servlet 类3.2 开启 Servlet 支持 1.…

力扣:1738. 找出第 K 大的异或坐标值

1738. 找出第 K 大的异或坐标值 给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 值 可由对所有满足 0 < i < a < m 且 0 < j < b < n 的元素 matrix[i][j]&#xff08;下标从 0 开始计数&…

晶圆厂的PE转客户工程师前景怎么样?

知识星球&#xff08;星球名&#xff1a; 芯片制造与封测技术社区&#xff0c;星球号&#xff1a; 63559049&#xff09;里的学员问&#xff1a; 目前在晶圆厂做PE&#xff0c;倒班oncall压力太大把身体搞坏了&#xff0c;现在有一个design house的CE客户工程师的offer&…

跨境选品师不是神话:普通人也能轻松掌握,开启全球贸易新篇章!

随着互联网技术的飞速发展&#xff0c;跨境电商行业已成为全球经济的新增长点。在这个背景下&#xff0c;一个新兴的职业——跨境选品师&#xff0c;逐渐走进了人们的视野。那么&#xff0c;跨境选品师究竟是做什么的?普通人又该如何成为优秀的跨境选品师呢? 一、跨境选品师的…

ABAQUS应用07-实现拉伸和压缩刚度不同的弹簧建模

文章目录 0、背景描述1、步骤 0、背景描述 到目前为止&#xff0c;本文的内容我还没有具体实践过&#xff0c;但是个人认为后期是会用到的。比如说&#xff0c;对于风电机组地基转动刚度的设置&#xff0c;土体就是一种拉压刚度并不相同的材料。所以现在先记录下来&#xff0c…

如何用Java实现SpringCloud Alibaba Sentinel的熔断功能?

在Java中使用Spring Cloud Alibaba Sentinel实现熔断功能的步骤如下&#xff1a; 添加依赖 在项目的pom.xml文件中添加Spring Cloud Alibaba Sentinel的依赖&#xff1a; <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud…

Java进阶学习笔记24——Object类

Object类: Object类是Java中所有类的祖宗类&#xff0c;因此&#xff0c;Java中所有类的对象都可以直接使用Object类中提供的一些方法。 所有类都是Object类的子孙类。 API文档&#xff1a; Object类的成员方法&#xff1a; Object类的常见方法&#xff1a; Student类&…