JDK的Future、Netty的Future、Netty的Promise
一、区别
继承关系 Netty中的Promise集成Netty中的Future集成JDK中的Future,也就是一开始Netty感JDK中的Future不还用,自己封装了一套Future,然后发现自己封装的Future不好用,又在此基础智商封装了Promise。现在说一下三者的区别:
- JDK的Future,只能同步的等待结果,知道线程执行完成(成功or失败),才能得到结果
- 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 | - | - | 设置失败结果 |
JDK的Future
package com.test.netty.c3;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j
public class TestJdkFuture {
public static void main(String[] args) throws Exception{
//1、关联线程池使用
ExecutorService executorService = Executors.newFixedThreadPool(2);
//2、提交任务
Future<Integer> f = executorService.submit(() -> {
log.debug("执行计算");
Thread.sleep(1000);
return 50;
});
//3、主线程通过get获取结果,阻塞方法
log.debug("等待结果");
//4、由执行任务的线程填充对象
log.debug("结果是:{}", f.get());
}
}
运行结果:
可以看到,计算是由子线程进行的,主线程在get()之后是阻塞到子线程执行完毕后,获取到结果。
Netty的Future
package com.test.netty.c3;
import io.netty.channel.EventLoop;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.Future;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TestNettyFuture {
public static void main(String[] args) throws Exception{
NioEventLoopGroup group = new NioEventLoopGroup();
EventLoop eventLoop = group.next();
Future<Integer> f = eventLoop.submit(() -> {
log.debug("执行计算");
Thread.sleep(1000);
return 70;
});
//3、主线程通过get获取结果,阻塞方法
// log.debug("等待结果");
// //4、由执行任务的线程填充对象
// log.debug("结果是:{}", f.get());
f.addListener(future -> log.debug("结果是:{}", future.getNow()));
}
}
执行结果:
可以看到,计算是子线程,获取结果也是子线程进行的
Netty的Promise
package com.test.netty.c3;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.DefaultPromise;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TestNettyPromise {
public static void main(String[] args) throws Exception{
//准备eventLoop
NioEventLoopGroup group = new NioEventLoopGroup();
//可以主动创建一个 promise 对象,结果的容器,任何线程可以向其中放结果
DefaultPromise<Integer> promise = new DefaultPromise<>(group.next());
new Thread(()->{
//线程计算完毕后,向promise填充结果
log.debug("开始计算....");
try {
int i = 1/0;
Thread.sleep(1000);
promise.setSuccess(100);
} catch (Exception e) {
e.printStackTrace();
promise.setFailure(e);
}
}).start();
//接受结果
log.debug("等待结果!");
log.debug("获取结果:{}", promise.cause());
}
}
在这里可以把Promise看做是结果的容器,任何线程都可以向容器中放入结果,放入成功结果setSuccess,放入失败异常setFailure