Reactive Programming How to use SerializedSubject

The Observable contract don't allow emitting items concurrently, that is you should not call the onNext onComplete, onError method from different thread concurrently.

You can emit items from different threads, but they are not parallel. Because in the essence, the stream is a sequence, a sequence means order and the strict before and after relationship between each item.

Suppose you have two operators on the chain, the first operator accept notifications on current thread, and you switch to another thread for second operator with observeOn method.

The two thread may running at the same time, but for the sequence, it's still sequential. The second thread will enqueue the items it receives and then emit them sequentially. There is an example in last post What ObserveOn and SubscribeOn do in Reactive Programming.

Run different operators on different threads will not break the contract because the library take care of calling the various on-methods. But if you calling those method in your own code, for example, you are implementing an event bus, to post events to the bus, you will call the onNext method.

You can actually break the contract if the invocations happens in different thread concurrently.

What the documentation says about this

When you use an ordinary Subject as a Subscriber, you must take care not to call its Observer.onNext(T) method (or its other on methods) from multiple threads, as this could lead to non-serialized calls, which violates the Observable contract and creates an ambiguity in the resulting Subject.

Here is where the SerializedSubject comes to the rescue. Just wrap your observable in SerializedSubject, you are safe.

Here is an example:

 
    public static void testSerializedSubject(){
        final Subject<Object, Object> subject = new SerializedSubject<>(PublishSubject.create());
        subject.subscribe(new Action1<Object>(){
            @Override
            public void call(Object obj){
                System.out.println("Receive " + obj);
            }
        });
        subject.onNext(3);
        subject.onNext(4);
    }