持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
Promise接口使用
Future接口调用线程需要通过线程池或者由FutureTask类创建,而后需要主线程执行get方法以获取结果,然后再执行相应的动作,其实有一种方式能够在调用线程时无须通过Future.get()方法获取到结果,就能进一步执行的动作,而这些回调的动作由执行Future任务的线程在执行完Future后自动调用,那方式就是使用Promise接口。
实现代码如下:
public class PromiseRun {
public static void main(String[] args) {
DefaultEventExecutor defaultEventExecutor = new DefaultEventExecutor();
Promise<String> promise = defaultEventExecutor.newPromise();
promise.addListener((FutureListener<String>)future-> System.out.println(future.get()));
defaultEventExecutor.submit(new Callable<String>(){
@Override
public String call() throws Exception {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
promise.setSuccess(String.valueOf(System.currentTimeMillis()));
return "Gxin";
}
});
defaultEventExecutor.shutdown();
try {
defaultEventExecutor.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:
[main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
1666335131350
注意点:
DefaultEventExecutor()方法是创建Netty默认执行器,由该执行器创建Promise对象,并且添加监听器,监视器将在任务完成时自动调用。promise.setSuccess(String)方法可以设置任务执行完成结果,此时会自动调用监听器。
因此,通过Promise接口,可以实现任务执行完成后自动回调,而不用调用线程通过Future接口调用get()方法获取结果后再处理结果,这才是真正的异步调用。
Volatile关键字使用
被volatile关键字修饰的变量,编译器和运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重新排序,在java并发编程中,该变量常用于防止指令重排序,在访问volatile变量时不会执行加锁操作,也就不会执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量的同步机制,但是这个机制仅仅只是保证了可见性而已。