Java Flow API 的实践(一):基本使用
概述
Flow API 是 Java 9 引入的响应式编程的接口,其中包含4个接口:
- Publisher:发布者,负责发布消息;
- Subscriber:订阅者,负责订阅处理消息;
- Subscription:订阅控制类,可用于发布者和订阅者之间通信;
- Processor:处理者,同时充当Publisher和Subscriber的角色。
各个接口之间关系如下图:
JDK中仅定义了接口规范,没有像 RxJava 那样直接可用的实现,因此适合有开发能力的组织基于这个接口规范开发自己的响应式框架(Andriod开发中要使用的话,仅需要定义Flow相关的类即可,参照JDK中的定义)。
示例
-
发布者:发布者根据指定间隔,按照订阅需求发送指定数量的计数:
class CountPublisher implements Flow.Publisher<Integer> { private int count = 0; //需要的计数值 private final long interval; //发送间隔 private boolean isCanceled; //是否被取消 public CountPublisher(long interval) { this.interval = interval; isCanceled = false; } @Override public void subscribe(Flow.Subscriber<? super Integer> subscriber) { new Thread(() -> { try { subscriber.onSubscribe(new CountSubscription()); for (int i = 0; i < count && !isCanceled; i++) { subscriber.onNext(i); Thread.sleep(interval); } subscriber.onComplete(); } catch (Exception e) { subscriber.onError(e); } }).start(); } private class CountSubscription implements Flow.Subscription { @Override public void request(long n) { count += n;//根据请求数新增计数值 } @Override public void cancel() { isCanceled = true;//将标志位置为已取消 } } }
-
订阅者:将指定计数值按10分组请求,并打印收到的计数值:
class CountSubscriber implements Flow.Subscriber<Integer> { private Flow.Subscription subscription; private int count; public CountSubscriber(int count) { this.count = count; } @Override public void onSubscribe(Flow.Subscription subscription) { this.subscription = subscription; /* 订阅时请求第一组 */ int requestCount = Math.min(10, count); count -= requestCount; subscription.request(requestCount); } @Override public void onNext(Integer item) { System.out.println("onNext:" + item); if ((item + 1) % 10 == 0 && count > 0) { //每组请求到后请求下一组 int requestCount = Math.min(10, count); count -= requestCount; subscription.request(requestCount); } } @Override public void onError(Throwable throwable) { System.out.println("onError:" + throwable); } @Override public void onComplete() { System.out.println("onComplete..."); } }
-
调用
CountPublisher publisher = new CountPublisher(500); CountSubscriber subscriber = new CountSubscriber(15); publisher.subscribe(subscriber); Thread.currentThread().join();
-
输出
onNext:0 onNext:1 onNext:2 onNext:3 onNext:4 onNext:5 onNext:6 onNext:7 onNext:8 onNext:9 onNext:10 onNext:11 onNext:12 onNext:13 onNext:14 onComplete...