📋jdk Future & netty Future & Promise 的区别
- jdk Future & netty Future & Promise 的区别
jdk Future
只能同步等待任务结束 才能拿到返回结果netty Future
支持同步等待结果返回,也支持异步的方式得到结果,但是两个都是要等任务结束才能拿到结果netty Promise
不支持包含 netty Future的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器
1️⃣java Future
Java自带的Future是用于处理异步任务的接口,主要用于异步操作的结果获取。通过调用异步方法返回的Future对象,可以在未来的某个时间点获取异步操作的结果。
- java Future提供了一些方法,如
isDone()
来检查任务是否已完成,get()
来获取执行结果(会阻塞直到结果就绪),cancel()
来取消任务等。
但是,Java自带的Future并没有提供一种方式来主动传递结果给Future,它只能被动地阻塞等待结果的到来。
@Slf4j
public class jdkFutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<Integer> submit = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
log.debug("开始计算--------------");
Thread.sleep(500);
return 100;
}
});
log.debug("等待计算结果--------------");
log.debug("获取计算结果--------------{}", submit.get());
log.debug("主线程流程完结");
}
}
控制台输出结果
netty-base- 2023-06-21 10:43:56 [pool-2-thread-1] DEBUG com.hrd.netty.c3.jdkFutureTest - 开始计算--------------
netty-base- 2023-06-21 10:43:56 [main] DEBUG com.hrd.netty.c3.jdkFutureTest - 等待计算结果--------------
netty-base- 2023-06-21 10:43:57 [main] DEBUG com.hrd.netty.c3.jdkFutureTest - 获取计算结果--------------100
netty-base- 2023-06-21 10:43:57 [main] DEBUG com.hrd.netty.c3.jdkFutureTest - 主线程流程完结
2️⃣Netty Future
在Netty中,
Future
是一个接口,用于表示异步操作的结果。它提供了一种方便的方式来处理异步任务的执行结果。
- Netty的
Future
接口定义了一些方法来处理异步操作的结果,包括:
isDone()
:检查操作是否已经完成。isSuccess()
:检查操作是否成功完成。cause()
:获取操作失败的原因。addListener()
:添加一个监听器,在操作完成时执行特定的操作。
@Slf4j
public class nettyFutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
NioEventLoopGroup eventExecutors = new NioEventLoopGroup(2);
Future<Integer> submit = eventExecutors.submit((Callable<Integer>) () -> {
log.debug("开始计算--------------");
Thread.sleep(1000);
return 100;
});
submit.addListener(future -> {
log.debug("等待计算结果--------------");
log.debug("获取计算结果--------------{}", future.getNow());
});
log.debug("主线程流程完结");
}
}
控制台输出结果
netty-base- 2023-06-21 10:44:45 [main] DEBUG com.hrd.netty.c3.nettyFutureTest - 主线程流程完结
netty-base- 2023-06-21 10:44:45 [nioEventLoopGroup-2-1] DEBUG com.hrd.netty.c3.nettyFutureTest - 开始计算--------------
netty-base- 2023-06-21 10:44:46 [nioEventLoopGroup-2-1] DEBUG com.hrd.netty.c3.nettyFutureTest - 等待计算结果--------------
netty-base- 2023-06-21 10:44:46 [nioEventLoopGroup-2-1] DEBUG com.hrd.netty.c3.nettyFutureTest - 获取计算结果--------------100
3️⃣Netty Promise
@Slf4j
public class nettyPromiseTest {
public static void main(String[] args) {
DefaultEventLoop defaultEventLoop = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(defaultEventLoop);
defaultEventLoop.execute(() -> {
log.debug("开始计算--------------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
promise.setSuccess(50);
});
defaultEventLoop.execute(() -> {
log.debug("开始计算--------------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
promise.setFailure(new RuntimeException());
});
promise.addListener(future -> {
log.debug("等待计算结果--------------");
log.debug("获取计算结果--------------{}", future.getNow());
});
log.debug("主线程流程完结");
}
}
控制台输出结果
netty-base- 2023-06-21 11:10:39 [defaultEventLoop-1-1] DEBUG com.hrd.netty.c3.nettyPromiseTest - 开始计算--------------
netty-base- 2023-06-21 11:10:39 [main] DEBUG com.hrd.netty.c3.nettyPromiseTest - 主线程流程完结
netty-base- 2023-06-21 11:10:40 [defaultEventLoop-1-1] DEBUG com.hrd.netty.c3.nettyPromiseTest - 等待计算结果--------------
netty-base- 2023-06-21 11:10:40 [defaultEventLoop-1-1] DEBUG com.hrd.netty.c3.nettyPromiseTest - 获取计算结果--------------50
netty-base- 2023-06-21 11:10:40 [defaultEventLoop-1-1] DEBUG com.hrd.netty.c3.nettyPromiseTest - 开始计算--------------
netty-base- 2023-06-21 11:10:41 [defaultEventLoop-1-1] WARN i.n.u.c.SingleThreadEventExecutor - Unexpected exception from an event executor:
java.lang.IllegalStateException: complete already: DefaultPromise@1a46227e(success: 50)
at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:106)
at com.hrd.netty.c3.nettyPromiseTest.lambda$main$1(nettyPromiseTest.java:39)
at io.netty.channel.DefaultEventLoop.run(DefaultEventLoop.java:54)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.RuntimeException: null
... 6 common frames omitted
📋总结
Future
接口的具体实现类是DefaultPromise
,它还实现了Promise
接口,扩展了Future
的功能。Promise
接口在Future
的基础上添加了主动设置操作结果的方法,例如:
setSuccess(result)
:设置操作成功完成,并指定结果。setFailure(cause)
:设置操作失败,并指定失败的原因。- 通过使用
Future
和Promise
,你可以以异步的方式执行任务,并在任务完成后获取结果。可以通过添加监听器来处理操作完成的>事件,或者通过等待Future
的结果来阻塞当前线程。- Netty的
Future
和Promise
提供了一种强大的方式来处理异步操作,使得在异步编程中能够更加方便和灵活地处理操作的结果和状态。