netty的Future接口继承了JDK的Future,且与之区别最大的是netty的future可以给Future添加监听器,当Future完成时会自动触发监听器的方法,而jdk的Future在编写代码时必须通过get方法同步等待才能获取到Future的结果。
//方式一
EventLoop eventLoop = new DefaultEventLoop();
Future<Integer> future = eventLoop.submit(() -> {
Thread.sleep(3000);
return 100;
});
log.info("result {}", future.get());
log.info("main end")
用传统future的方式,调用get方法,主线程阻塞了,且需要get方法返回后,后续代码才可以继续执行
EventLoop eventLoop = new DefaultEventLoop();
Future<Integer> future = eventLoop.submit(() -> {
Thread.sleep(3000);
return 100;
});
future.addListener(future1 -> log.info("result = {}", future1.getNow()));
log.info("main end");
通过netty提供的监听器模式,主线程不会阻塞,而是继续运行,当Future完成后会自动回调listener的方法,netty的编程模式基本都是这种异步非阻塞的模式,如果需要阻塞调用线程,可以调用sync方法来等待future的完成
在netty中还有另外一个很重要的接口Promise,继承自Netty的Future接口,并且还提供了可以对Future设置结果的方法。这也是Promise与Future的最大区别,Future的结果都是提交给线程池,由线程池返回的,应用程序无法再干预,而Promise是应用程序可以对其进行操作,如下
EventLoop eventLoop = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
promise.setSuccess(8);
//promise.setFailure(new IllegalStateException()); 也可以设置失败
}, "t1").start();
new Thread(() -> {
promise.addListener(future -> {
Object futureNow = future.getNow();
log.info("future result {}", futureNow);
});
}, "t2").start();
从这个例子可以看出,promise可以在多个线程间通讯,且对应用程序来说可以灵活的控制结果。
熟悉netty的Future和Promise原理与使用对编写netty应用程序和了解源码有非常大的帮助









网友评论