Future&Promise
1. 概述
netty中的Future与jdk中的Future同名,但是是两个接口,netty的Future继承自jdk的Future,而Promise又对netty中的Future进行了扩展:
- jdk Future只能同步等待任务结束(或成功、或失败)才能得到结果
- netty Future可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束
- netty Promise不仅有netty Future的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器
API | jdk Future | netty Future | Promise |
---|---|---|---|
cancel | 取消任务 | - | - |
isCanceled | 任务是否取消 | - | - |
isDone | 任务是否完成,不能区分成功失败 | - | - |
get | 获取任务结果,阻塞等待 | - | - |
getNow | - | 获取任务结果,非阻塞,还未产生结果时返回 null | - |
await | - | 等待任务结束,如果任务失败,不会抛异常,而是通过 isSuccess 判断 | - |
sync | - | 等待任务结束,如果任务失败,抛出异常 | - |
isSuccess | - | 判断任务是否成功 | - |
cause | - | 获取失败信息,非阻塞,如果没有失败,返回null | - |
addLinstener | - | 添加回调,异步接收结果 | - |
setSuccess | - | - | 设置成功结果 |
setFailure | - | - | 设置失败结果 |
2. java的Future使用
java
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = () -> {
logger.info("开始执行任务");
Thread.sleep(1000);
return 1;
};
// 创建线程池使用callable接口
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<Integer> future = executorService.submit(callable);
Integer result1 = future.get();
logger.info("计算结果:{}", result1);
}
运行结果:
3. netty中Future使用
java
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = () -> {
logger.info("开始执行任务");
Thread.sleep(1000);
return 1;
};
NioEventLoopGroup group = new NioEventLoopGroup(2);
Future<Integer> future = group.submit(callable);
// 阻塞等待结果返回
// Integer result1 = future.get();
// 异步回调的方式得到结果
future.addListener(new GenericFutureListener<Future<Integer>>() {
@Override
public void operationComplete(Future<Integer> future) throws Exception {
Integer result = future.getNow();
logger.info("计算结果:{}", result);
}
});
}
运行结果: jdk中的Future和netty中的Future相同点是都不是我们直接创建的,而是通过方法返回的,除了创建还有结果的设置都是线程内部设置的,不对开发者开放。
4. netty中Promise使用
4.1 基本使用
java
public static void main(String[] args) throws ExecutionException, InterruptedException {
EventLoop eventLoop = new DefaultEventLoopGroup().next();
// 手动创建一个promise对象
DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
eventLoop.execute(() -> {
logger.info("开始执行任务");
try {
Thread.sleep(3000);
// 手动设置结果
promise.setSuccess(99);
} catch (InterruptedException e) {
promise.setFailure(e);
}
});
logger.info("start...");
logger.info("计算结果:{}", promise.getNow()); // 还没有结果
logger.info("计算结果:{}", promise.get());
logger.info("任务执行完成");
}
运行结果如下:
4.2 使用await
java
public static void main(String[] args) throws ExecutionException, InterruptedException {
EventLoop eventLoop = new DefaultEventLoopGroup().next();
// 手动创建一个promise对象
DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
eventLoop.execute(() -> {
logger.info("开始执行任务");
try {
Thread.sleep(3000);
// 手动设置结果
int i = 1 / 0;
promise.setSuccess(99);
} catch (Exception e) {// 需要把所有异常都捕获,避免直接抛出不走catch块
promise.setFailure(e);
}
});
logger.info("start...");
promise.await(); // 同步阻塞但是不会抛出异常
logger.info("等待结果...");
logger.info("结果:{}", promise.getNow());
// 通过判断拿结果
logger.info("结果:{}", promise.isSuccess() ? promise.getNow() : promise.cause());
logger.info("任务执行完成");
}
运行效果: