jdk9 reactive stream

背压:

是指由于生产者生产速度过快,而造成消费者无法及时处理更多的事件而产生的问题,背压是该问题的一个解决方案,它可以通过主动从生产者拉取事件消费而避免过多事件推送而无法处理的情况,或者减缓事件发布的速率直到可以处理更多的事件,实现事件流的流量控制。

reactive stream是一套基于发布/订阅模式的数据处理的规范,主要目标是管理跨异步边界的流数据交换 - 考虑将元素传递到另一个线程或线程池 - 同时确保接收方不会强制缓冲任意数量的数据。换句话说,背压是该模型的组成部分,以便允许在线程之间调解的队列有界。如果背压信号是同步的,则异步处理的好处将被否定,因此需要注意强制实施Reactive Streams实现的所有方面的完全非阻塞和异步行为。对应的是flow api

publisher:数据的发布者、生产者

 public void subscribe(Subscriber<? super T> subscriber);//与订阅者建立关系

subscriber:数据的订阅者、消费者

public void onSubscribe(Subscription subscription);//建立订阅关系时执行
public void onNext(T item);//数据接收时执行
public void onError(Throwable throwable);//出错时执行
public void onComplete();//发布者无更多数据时调用,表示处理完毕时执行

subscription:维持发布者与订阅者的关系,一个订阅认证

public void request(long n);//请求n条数据
public void cancel();//取消请求数据

processor:过滤器,数据处理器,继承了publisher和subscriber

下面这个例子是

package com.gdut.nettydemo.flow;

import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * @author lulu
 * @Date 2019/8/7 13:09
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService fix= Executors.newFixedThreadPool(3);
        SubmissionPublisher<Integer> publisher = new SubmissionPublisher();



        //订阅者
        Flow.Subscriber subscriber = new Flow.Subscriber() {
            private Flow.Subscription subscription;
            long start=0;
            @Override
            public void onSubscribe(Flow.Subscription subscription) {
                start=System.currentTimeMillis();
                System.out.println("haha");
                this.subscription = subscription;
                this.subscription.request(1);
            }

            @Override
            public void onNext(Object item) {
                try {
                    //睡眠时间如果更长的话,会发现sumbit方法被阻塞了,而offer方法则不会阻塞,会执行删除该事件的方法,如果符合条件会进行重投
                    TimeUnit.MILLISECONDS.sleep(1000);
                 /*   fix.submit(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName()+"接收到数据" + item);
                        }
                    });*/
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"接收到数据" + item);

                this.subscription.request(3);
            }

            @Override
            public void onError(Throwable throwable) {
                this.subscription.cancel();
            }

            @Override
            public void onComplete() {
                System.out.println("处理完毕"+(System.currentTimeMillis()-start));
//                fix.shutdown();
            }
        };
//建立关系
        publisher.subscribe(subscriber);
        //submit
//        IntStream.range(0,1000).forEach(publisher::submit);
        IntStream.range(0,300).forEach(e->{
           int t= publisher.offer(e,70,TimeUnit.MILLISECONDS,(pr,d)->
d>280
            );
            System.out.println(t+"--"+e);
        });
        publisher.close();
        Thread.currentThread().join(3000000);
    }
}

符合offer里的条件会执行断点的retrayOffer方法,即使可以重投,在规定时间内没有空位就默认为失败。

也可以自定义Processor来对数据做一定的数据处理

package com.gdut.nettydemo.flow;

import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;

public class ProcessorDemo extends SubmissionPublisher<String>
        implements Flow.Processor<Integer, String> {

    private Flow.Subscription subscription;

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        // 保存订阅关系, 需要用它来给发布者响应
        this.subscription = subscription;

        // 请求一个数据
        this.subscription.request(1);
    }

    @Override
    public void onNext(Integer item) {


        // 保留能整除2的
        if (item %2==0) {
            this.submit("转换后的数据:" + item);
        }

        this.subscription.request(1);

        // 达到了目标, 调用cancel告诉发布者不再接受数据了
        // this.subscription.cancel();
    }

    @Override
    public void onError(Throwable throwable) {
        // 出现了异常(例如处理数据的时候产生了异常)
        throwable.printStackTrace();

        this.subscription.cancel();
    }

    @Override
    public void onComplete() {
        // 关闭
        this.close();
    }

}
package com.gdut.nettydemo.flow;

import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
import java.util.stream.IntStream;

/**
 * @author lulu
 * @Date 2019/8/7 21:12
 */
public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        SubmissionPublisher publisher=new SubmissionPublisher();
        ProcessorDemo processor=new ProcessorDemo();
        Flow.Subscriber subscriber=new Flow.Subscriber() {
            private Flow.Subscription subscription;
            @Override
            public void onSubscribe(Flow.Subscription subscription) {
                this.subscription=subscription;
                this.subscription.request(1);
            }

            @Override
            public void onNext(Object item) {
                System.out.println("接收到数据"+item);
                this.subscription.request(1);
            }

            @Override
            public void onError(Throwable throwable) {
                this.subscription.cancel();
            }

            @Override
            public void onComplete() {
                System.out.println("处理完了");
            }
        };
//建立关系
        publisher.subscribe(processor);
        processor.subscribe(subscriber);

        IntStream.range(0,100).forEach(publisher::submit);
        publisher.close();
        Thread.currentThread().join(10000);
    }

}

参考博文:

https://yanbin.blog/java-9-talk-reactive-stream/#more-8877

https://www.cnblogs.com/IcanFixIt/p/7245377.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值