1、响应式编程基础概念

本文介绍了响应式编程的基础,重点讨论了响应式流规范中的四个主要接口和背压机制。背压是防止下游模块过载的机制,而响应式流规范定义了发布者、订阅者和订阅的概念,其中Subscriber通过request()方法控制接收数据的速率,避免压垮处理模块。

为了实现更高的资源利用率,使用异步非阻塞交互模型

背压是指处理模块之间工作负载的一种机制,通过向上游传播信号,保证不会压垮下一个模块

观察者模式(Observer Pattern)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在这里插入图片描述


public interface Observer {
    void update(String event);
}

class Subject {
 
    private final List<Observer> observers = new ArrayList<>();
  
    private void notifyObservers(String event) {
        observers.forEach(observer -> observer.update(event));
    }
  
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
  
    public void scanSystemIn() {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            notifyObservers(line);
        }
    }
}

public class ObserverDemo {
    public static void main(String[] args) {
        System.out.println("Enter Text : ");
        Subject subject = new Subject();
        
        subject.addObserver(event -> {
            System.out.println("Received response: " + event);
        });

        subject.scanSystemIn();
    }
}

响应式流规范基础知识

响应式流规范定义了四个主要接口:PublisherSubscriberSubscriptionProcessor。由于该规范发展独立于任何组织,所以作为单独的jar包获取,所有接口做在 org.reactivestreams 包中。
在这里插入图片描述

A Publisher can push new values to its Subscriber (by calling onNext) but can also signal an error (by calling onError) or completion (by calling onComplete). Both errors and completion terminate the sequence.

This can be summed up as follows:
onNext x 0..N [onError | onComplete]

Publisher

发布者


/**
 * Publisher is a provider of a potentially unbounded number of sequenced elements, publishing them according to the demand received from its Subscriber.
 * 
 * Publisher can serve multiple Subscriber subscribed dynamically at various points in time.
 *
 */
public interface Publisher<T> {

    /**
     * Request Publisher to start streaming data.
     * 
     * This is a "factory method" and can be called multiple times, each time starting a new Subscription.
     * 
     * Each Subscription will work for only a single Subscriber.
     * 
     * A Subscriber should only subscribe once to a single Publisher.
     * 
     * If the Publisher rejects the subscription attempt or otherwise fails it will signal the error via Subscriber#onError.
     *
     * @param s the Subscriber that will consume signals from this Publisher
     */
    public void subscribe(Subscriber<? super T> s);
}

Subscriber

订阅者


/**
 * Will receive call to  #onSubscribe(Subscription)} once after passing an instance of Subscriber to Publisher#subscribe(Subscriber)
 * 
 * No further notifications will be received until Subscription#request(long) is called.
 * <p>
 * After signaling demand:
 * 
 *     One or more invocations of #onNext(Object) up to the maximum number defined by Subscription#request(long)
 *     Single invocation of #onError(Throwable) or #onComplete() which signals a terminal state after which no further events will be sent.
 * 
 * Demand can be signaled via Subscription#request(long) whenever the Subscriber instance is capable of handling more.
 *
 * @param <T> the type of element signaled.
 */
public interface Subscriber<T> {
    /**
     * Invoked after calling Publisher#subscribe(Subscriber)
     * 
     * No data will start flowing until Subscription#request(long) is invoked.
     *
     * It is the responsibility of this Subscriber instance to call Subscription#request(long) whenever more data is wanted.
     *
     * The Publisher will send notifications only in response to Subscription#request(long).
     * 
     * @param s Subscription that allows requesting data via Subscription#request(long)
     */
    public void onSubscribe(Subscription s);

    /**
     * Data notification sent by the Publisher in response to requests to Subscription#request(long)
     * 
     * @param t the element signaled
     */
    public void onNext(T t);

    /**
     * Failed terminal state.
     * 
     * No further events will be sent even if Subscription#request(long) is invoked again.
     *
     * @param t the throwable signaled
     */
    public void onError(Throwable t);

    /**
     * Successful terminal state.
     *
     * No further events will be sent even if Subscription#request(long) is invoked again.
     */
    public void onComplete();
}

Subscription

订阅

为控制元素提供基础

  • cancel() 方法能取消对流的订阅甚至完全取消发布
  • request() 扩展了 Publisher 和 Subscriber 之间的交互能力,为了通知Publisher应该推送多少数据,Subscriber可以通过 request 方法发出数量的信号,确保传入元素的数量不会超过限制

/**
 * A Subscription represents a one-to-one lifecycle of a Subscriber subscribing to a Publisher.
 *
 * It can only be used once by a single Subscriber
 * 
 * It is used to both signal desire for data and cancel demand (and allow resource cleanup).
 *
 */
public interface Subscription {
    /**
     * No events will be sent by a Publisher until demand is signaled via this method.
     *
     *  It can be called however often and whenever needed—but if the outstanding cumulative demand ever becomes Long.MAX_VALUE or more,
     *  it may be treated by the Publisher as "effectively unbounded".
     *
     * Whatever has been requested can be sent by the Publisher so only signal demand for what can be safely handled.
     *
     * A Publisher can send less than is requested if the stream ends but then must emit either Subscriber#onError(Throwable) or Subscriber#onComplete()
     * 
     * @param n the strictly positive number of elements to requests to the upstream Publisher
     */
    public void request(long n);

    /**
     * Request the Publisher to stop sending data and clean up resources.
     * 
     * Data may still be sent to meet previously signalled demand after calling cancel.
     */
    public void cancel();
}

Processor

/**
 * A Processor represents a processing stage—which is both a Subscriber
 * and a Publisher and obeys the contracts of both.
 *
 * @param <T> the type of element signaled to the {@link Subscriber}
 * @param <R> the type of element signaled by the {@link Publisher}
 */
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值