Java异步非阻塞编程的几种方式


今天读到一篇博客,发现对Java异步非阻塞编程概念有些模糊了,趁此整理了一下常用的几种编程方式。

方式一:同步调用

当主线程发起IO操作时,会被阻塞,一直等到数据返回,此时主线程状态是Runnable状态。产生的问题是:主线程在IO等待的过程中,线程资源没有得到充分的利用,对于大量IO场景的业务吞吐量会有一定限制。如下图:
在这里插入图片描述

方式二:Future方式异步调用

使用future异步获取结果代码示例如下:

ThreadPoolExecutor executor = new ThreadPoolExecutor(......);
     Future<Boolean> future = (Future<Boolean>) executor.submit(new Runnable() {
            @Override
            public void run() {
                // 复杂计算
            }
     });
     boolean result = future.get(1000, TimeUnit.MILLISECONDS);	

主线程等待示意图如下,此时主线程在等待时间内需要让出cpu,cpu可以做些其他事情,但主线程仍然阻塞(主线程由Runnable状态变为waiting状态):
在这里插入图片描述
上述示意代码返回的Future实例是FutureTask类,类图如下,详细分析可参考FutureTask-get方法。
在这里插入图片描述

方式三:Callback回调方式

Callback回调方式可参考示意图如下:
在这里插入图片描述
对Callback回调机制简要举个例子如下:

// 回调接口
    public interface ICallback {
     	public void callback(String parameter);
    }	
     
     // 异步执行的业务
    public class CallbackTest {
    	private ExecutorService threadPool = Executors.newFixedThreadPool(2);
    	public void doSyncInvoke(ICallback callback) {
    		Thread thread = new Thread(new Runnable() {
            	@Override
            	public void run() {
                	System.out.println("子线程任务处理");

                	// 开始处理业务
                	String result = "this is process result";

                	// 执行回调函数
                	callback.callback(result);
            	}
        	});

        	// 交给线程池执行
        	threadPool.submit(thread);
        	threadPool.shutdown();
    	}
    }
    
    // 主函数调用
    CallbackTest callbackTest = new CallbackTest();
    callbackTest.doSyncInvoke(new ICallback() {
            @Override
            public void callback(String parameter) {
                System.out.println("执行回调函数......");
            }
    });
    
    /**
     *输出:
     * 子线程任务处理
     * 执行回调函数......
     **/

另外,Java8提供了CompletableFuture可使用,使用示例如下:

// 输出:hello world Java
     CompletableFuture.supplyAsync(() -> "Hello") // 异步处理,类似上述doSyncInvoke
                .thenApply(s -> s + " world ") // 回调函数
                .thenApply(String::toLowerCase) // 回调函数
                .thenCombine(CompletableFuture.completedFuture("Java"), (s1, s2) -> s1 + s2)
                .thenAccept(System.out::println);	

另外CompletableFuture的类图如下:
在这里插入图片描述

方式四:Java9 Reactive Streams

该种方法不再细述,可参考相关资料。

参考:https://mp.weixin.qq.com/s/AVMN8jyqMXWhE9bRs_e0aQ

欢迎关注微信公众号:方辰的博客
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值