李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
07.Netty之Future与Promise
Leefs
2022-06-10 PM
1032℃
0条
[TOC] ### 一、概述 Future与Promise在异步处理时,经常用到这两个接口 首先要说明 netty 中的 Future 与 jdk 中的 Future 同名,但是是两个接口,**netty 的 Future 继承自 jdk 的 Future,而 Promise 又对 netty Future 进行了扩展**。 * **jdk Future**:只能同步等待任务结束(或成功、或失败)才能得到结果; * **netty Future**:可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束; * **netty Promise**:不仅有 netty Future 的功能,而且脱离了任务独立存在,**只作为两个线程间传递结果的容器**。 | 功能/名称 | jdk Future | netty Future | Promise | | ------------ | ------------------------------ | ------------------------------------------------------------ | ------------ | | cancel | 取消任务 | - | - | | isCanceled | 任务是否取消 | - | - | | isDone | 任务是否完成,不能区分成功失败 | - | - | | get | 获取任务结果,阻塞等待 | - | - | | getNow | - | 获取任务结果,非阻塞,还未产生结果时返回 null | - | | await | - | 等待任务结束,如果任务失败,不会抛异常,而是通过 isSuccess 判断 | - | | sync | - | 等待任务结束,如果任务失败,抛出异常 | - | | isSuccess | - | 判断任务是否成功 | - | | cause | - | 获取失败信息,非阻塞,如果没有失败,返回null | - | | addLinstener | - | 添加回调,异步接收结果 | - | | setSuccess | - | - | 设置成功结果 | | setFailure | - | - | 设置失败结果 | ### 二、使用 + #### 2.1 JDK Future ```java import lombok.extern.slf4j.Slf4j; import java.util.concurrent.*; /** * @author lilinchao * @date 2022/6/9 * @description JDK Future **/ @Slf4j public class TestJdkFuture { public static void main(String[] args) throws ExecutionException, InterruptedException { //1.创建线程池 ExecutorService service = Executors.newFixedThreadPool(2); //2.提交任务 Future
future = service.submit(new Callable
() { @Override public Integer call() throws Exception { log.info("执行计算"); Thread.sleep(5000); return 100; } }); log.info("等待结果..."); //主线程通过future获取结果,阻塞等待结果返回 Integer integer = future.get(); log.info("result:{}",integer); } } ``` **运行结果** ``` 09:11:15.931 [main] INFO com.lilinchao.netty.future.TestJdkFuture - 等待结果... 09:11:16.059 [pool-1-thread-1] INFO com.lilinchao.netty.future.TestJdkFuture - 执行计算 09:11:21.071 [main] INFO com.lilinchao.netty.future.TestJdkFuture - result:100 ``` #### 2.2 Netty Future ```java import io.netty.channel.EventLoop; 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; /** * @author lilinchao * @date 2022/6/9 * @description Netty Future **/ @Slf4j public class TestNettyFuture { public static void main(String[] args) throws ExecutionException, InterruptedException { NioEventLoopGroup group = new NioEventLoopGroup(); EventLoop eventLoop = group.next(); Future
future = eventLoop.submit(new Callable
() { @Override public Integer call() throws Exception { log.info("计算中..."); Thread.sleep(5000); return 100; } }); // 主线程中获取结果 // System.out.println(Thread.currentThread().getName() + " 获取结果"); // System.out.println("getNow " + future.getNow()); // System.out.println("get " + future.get()); //异步 future.addListener(new GenericFutureListener
>() { @Override public void operationComplete(Future super Integer> future) throws Exception { log.info("result:{}",future.getNow()); } }); } } ``` **运行结果** ```java 09:14:00.656 [nioEventLoopGroup-2-1] INFO com.lilinchao.netty.future.TestNettyFuture - 计算中... 09:14:05.662 [nioEventLoopGroup-2-1] INFO com.lilinchao.netty.future.TestNettyFuture - result:100 ``` **说明** Netty中的Future对象,可以通过EventLoop的sumbit()方法得到 - 可以通过Future对象的**get方法**,阻塞地获取返回结果 - 也可以通过**getNow方法**,获取结果,若还没有结果,则返回null,该方法是非阻塞的 - 还可以通过**future.addListener方法**,在Callable方法执行的线程中,异步获取返回结果 #### 2.3 Netty Promise Promise相当于一个容器,可以用于存放各个线程中的结果,然后让其他线程去获取该结果 ```java 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; /** * @author lilinchao * @date 2022/6/9 * @description Promise 示例 **/ @Slf4j public class TestNettyPromise { public static void main(String[] args) throws ExecutionException, InterruptedException { //1.准备 EventLoop 对象 NioEventLoopGroup group = new NioEventLoopGroup(); EventLoop loop = group.next(); //2.可以主动创建 promise, 结果容器 DefaultPromise
promise = new DefaultPromise<>(loop); new Thread(() -> { //3.任意一个线程执行计算,计算完毕后向 promise 填充结果 log.info("开始计算..."); try { // int i = 1 / 0; Thread.sleep(5000); promise.setSuccess(80); } catch (InterruptedException e) { e.printStackTrace(); promise.setFailure(e); } }).start(); //4.接收结果的线程 log.info("waiting..."); log.info("result:{}",promise.get()); } } ``` **运行结果** ``` 09:23:53.532 [main] INFO com.lilinchao.netty.future.TestNettyPromise - waiting... 09:23:53.600 [Thread-0] INFO com.lilinchao.netty.future.TestNettyPromise - 开始计算... 09:23:58.612 [main] INFO com.lilinchao.netty.future.TestNettyPromise - result:80 ``` *附参考文章:* *《黑马程序员Netty教程》*
标签:
Netty
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2149.html
上一篇
06.Netty组件Channel介绍
下一篇
08.Netty之Handler与Pipeline
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Spark Streaming
HDFS
Ubuntu
Spring
队列
Yarn
Netty
Typora
Jquery
ajax
Shiro
Jenkins
VUE
ClickHouse
排序
高并发
SQL练习题
Sentinel
Http
机器学习
Hadoop
Python
Azkaban
DataX
MyBatisX
JavaScript
二叉树
LeetCode刷题
Java阻塞队列
人工智能
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭