Rxjava thread scheduling Source Analysis __java

Source: Internet
Author: User
Tags static class

First of all, asynchronous request or read data is a common development of a function, after the successful data acquisition needs to be shown to the main thread of the UI, usually we are through the handler for conversion.
The usual wording:

The pseudocode implementation is similar to
new Thread (new Runnable () {
    void run () {
        //) to implement the conversion via Handler
        handler.sendmessage () ...
    }
);

Handler Handler = new Handler () {
    void Handlemessage () {...}}
}

In contrast to the rxjava of the chain-type constantly open writing:

Observable.create (New observableonsubscribe<string> () {
   @Override public
   void Subscribe ( Observableemitter<string> e) throws Exception {
       E.onnext ("1");
       E.oncomplete ();
   }})
 . Subscribeon (Schedulers.io ())
 . Observeon (Androidschedulers.mainthread ())
 . Subscribe (New consumer< String> () {
    @Override public
    Void Accept (String s) throws Exception {
        //get the corresponding data ...
    }
});

In Rxjava, it is through the Subscribeon Observeon these two methods to achieve the switch between the thread to the main thread, this is a most basic thread switching method so the purpose of this article is to analyze the two methods in the end to do what ... analysis of various observable generation

At first we still went into observable.create. Previous source analysis Once he was directly returned to a observablecreate here it is best to remember clearly, because the following will return a variety of observable objects:

This is the first method to invoke public
static <T> observable<t> Create (observableonsubscribe<t> source) {
    Return rxjavaplugins.onassembly (new observablecreate<t> (source));
}

This is the returned type Public
final class Observablecreate<t> extends observable<t> {
    final Observableonsubscribe<t> Source;

    Public observablecreate (observableonsubscribe<t> source) {
        This.source = source;
    }
}

For the time being, there is no impediment to the Subscribeon approach:

The method called is public
final observable<t> Subscribeon (Scheduler Scheduler) {
    objecthelper.requirenonnull ( Scheduler, "Scheduler is null");
    Return rxjavaplugins.onassembly (The new observablesubscribeon<t> (this, scheduler));
}

Subscribeon returns the type public
final class Observablesubscribeon<t> extends abstractobservablewithupstream< T, t> {
    final Scheduler Scheduler;

    Public Observablesubscribeon (observablesource<t> source, Scheduler Scheduler) {
        super (source);
        This.scheduler = Scheduler;
    }

Abstractobservablewithupstream<t, u> extends observable<u> so that means subscribeon this method actually generates a observable, okay, See how many he can generate to continue the analysis; Enter Observeon:

//invoke Observeon method public final observable<t> Observeon (Scheduler Scheduler, Boolean
    delayerror, int buffersize) {objecthelper.requirenonnull (Scheduler, "Scheduler is null");
    Objecthelper.verifypositive (buffersize, "buffersize");
Return rxjavaplugins.onassembly (The new observableobserveon<t> (this, scheduler, Delayerror, buffersize)); }//return type Public final class Observableobserveon<t> extends Abstractobservablewithupstream<t, t> {final
    Scheduler Scheduler;
    Final Boolean delayerror;
    final int buffersize;
        Public Observableobserveon (observablesource<t> source, Scheduler Scheduler, boolean delayerror, int buffersize) {
        Super (source);
        This.scheduler = Scheduler;
        This.delayerror = Delayerror;
    This.buffersize = buffersize; }
}

Good and returned to a observableobserveon; Yes, it's a new observable, but our Observeron method is called after Subscribeon, which means Observeon the last new Observableobserveon<t> (this, scheduler, Delayerror, buffersize) The incoming this object, which is the source variable in the Observableobserveon, is the Observablesubscribeon object; here, a layer of observable is not to be confused. schedulers Simple Analysis

Public abstract class Scheduler {public

    abstract Worker createworker ();

    public abstract Static class Worker implements disposable {public
        abstract disposable Schedule (@NonNull Runnable Run, Long delay, @NonNull timeunit unit);
    }

First you need to look at scheduler. This is an abstract class, and I've listed two abstract methods and abstract classes that need to be rewritten, schedulers in fact, it's all constant. It's a more straightforward way of encapsulating a thread pool that can be invoked more directly inside.

Public final class Schedulers {@NonNull static final Scheduler single;

    @NonNull static final Scheduler computation;

    @NonNull static final Scheduler IO;

    @NonNull static final Scheduler trampoline;

    @NonNull static final Scheduler new_thread;
    Static Final class Singleholder {static final Scheduler DEFAULT = new Singlescheduler ();
    Static Final class Computationholder {static final Scheduler DEFAULT = new Computationscheduler ();
    Static Final class Ioholder {static final Scheduler DEFAULT = new Ioscheduler ();
    Static Final class Newthreadholder {static final Scheduler DEFAULT = new Newthreadscheduler ();

        static {single = Rxjavaplugins.initsinglescheduler (new Singletask ());

        computation = Rxjavaplugins.initcomputationscheduler (New Computationtask ());

        IO = Rxjavaplugins.initioscheduler (New Iotask ()); trampoline = Trampolinescheduler.Instance ();
    New_thread = Rxjavaplugins.initnewthreadscheduler (New Newthreadtask ()); }
}

We take a look at the Schedulers.io in our example, is actually the class Ioscheduler:

    Public Ioscheduler () {This
        (worker_thread_factory);
    }

    Public Ioscheduler (Threadfactory threadfactory) {
        this.threadfactory = threadfactory;
        This.pool = new atomicreference<cachedworkerpool> (NONE);
        Start ();
    }

    @Override public
    void Start () {
        Cachedworkerpool update = new Cachedworkerpool (Keep_alive_time, Keep_alive_ Unit, threadfactory);
        if (!pool.compareandset (NONE, update)) {
            update.shutdown ();
        }
    }

Here is the main encapsulation of a thread pool Cachedworkerpool class, of course, the specific thread pool how to encapsulate the expansion of the sense of space will be very long, first skipped; basically everyone can read. The final Subscribe analysis

Because of that, subscribe this method is written in the back of the Observeon the observable that was first executed was Observableobserveon, and finally the following methods were executed:

protected void Subscribeactual (observer<. Super t> Observer) {
    if (scheduler instanceof) {
        SOURCE.SUBSCRIBE (Observer);
    } else {
        Scheduler.worker w = scheduler.createworker ();
        Source.subscribe (new Observeonobserver<t> (Observer, W, Delayerror, buffersize));
    }

Into Scheduler.createworker because the scheduler here is androidschedulers:

Public Worker Createworker () {return new Handlerworker (handler);}
   Private static final class Handlerworker extends Worker {private final Handler Handler; @Override Public Disposable Schedule (Runnable run, long delay, timeunit unit) {if (run = null) throw new NULLP
       Ointerexception ("Run = null");

       if (unit = = null) throw new NullPointerException ("unit = = null");
       if (disposed) {return disposables.disposed ();

       Run = Rxjavaplugins.onschedule (run);

       scheduledrunnable scheduled = new Scheduledrunnable (handler, run);
       Message message = Message.obtain (handler, scheduled); Message.obj = this;

       Used as token for batch disposal of the This worker ' s runnables.

       handler.sendmessagedelayed (Message, Math.max (0L, Unit.tomillis (delay));
       Re-check disposed State for removing in case we were racing a call to Dispose ().
           if (disposed) {handler.removecallbacks (scheduled); RetuRN disposables.disposed ();
   return scheduled; }
}

This time to understand why we have to first talk about the common two methods of scheduler, because these two methods are our most concerned.
Enter Source.subscribe (new Observeonobserver<t> (Observer, W, Delayerror, buffersize)) The incoming observer in this method is the data receiving observer that we passed in the activity, when the execution Source.subscribe executes the Observablesubscribeon.subscribeactual method:

public void subscribeactual (final observer< Super t> s) {
    final subscribeonobserver<t> parent = new SUBSC Ribeonobserver<t> (s);

    S.onsubscribe (parent);

    Parent.setdisposable (Scheduler.scheduledirect (new Subscribetask (parent));
}

We mainly look at Scheduler.scheduledirect (new Subscribetask), to be clear subscribetask this is a runnable:

Public disposable Scheduledirect (@NonNull Runnable Run, long delay, @NonNull timeunit unit) {
    final Worker w = Createw Orker ();

    Final Runnable Decoratedrun = Rxjavaplugins.onschedule (run);

    Disposetask task = new Disposetask (Decoratedrun, W);

    W.schedule (task, delay, unit);

    return task;
}

It's natural to finally perform the Worker.schedule:

Public Worker Createworker () {return
    new Eventloopworker (Pool.get ());
}

Static final class Eventloopworker extends Scheduler.worker {

    @NonNull
    @Override public
    Disposable  Schedule (@NonNull Runnable action, long delaytime, @NonNull timeunit unit) {
        if (tasks.isdisposed ()) {
            //don ' t Schedule, we are unsubscribed return
            emptydisposable.instance;
        }

        Return threadworker.scheduleactual (Action, Delaytime, Unit, tasks);
    }

This is mainly to enter the last line of code threadworker.scheduleactual:

Public scheduledrunnable scheduleactual (final Runnable run, long delaytime, @NonNull timeunit unit, @Nullable Disposablec Ontainer parent) {
    Runnable Decoratedrun = Rxjavaplugins.onschedule (run);

    scheduledrunnable sr = new Scheduledrunnable (decoratedrun, parent);

    if (parent!= null) {
        if (!parent.add (SR)) {return
            sr;
        }
    }

    Future<?> F;
    try {
        if (delaytime <= 0) {
            f = executor.submit ((callable<object>) SR);
        } else {
            f = executor. Schedule ((callable<object>) SR, Delaytime, Unit);
        }
        Sr.setfuture (f);
    } catch (Rejectedexecutionexception ex) {
        if (parent!= null) {
            parent.remove (SR);
        }
        Rxjavaplugins.onerror (ex);
    }

    return SR;
}

As soon as we see executor.submit we know that this is where we put the thread pool to perform the asynchronous operation, so of course it depends on the runnable:

Final class Subscribetask implements Runnable {
    private final subscribeonobserver<t> parent;

    Subscribetask (subscribeonobserver<t> parent) {
        this.parent = parent;
    }

    @Override public
    Void Run () {
        source.subscribe (parent);
    }
}

A very empty sentence: Source.subscribe (parent) Remember we said before that the source here is the first Observablecreate object declared, That is, the observableonsubscribe related methods that we write in the activity are executed:

We can do some asynchronous code
new Observableonsubscribe<string> () {
  @Override public
  void in subscribe Subscribe (observableemitter<string> e) throws Exception {
          E.onnext ("1");
          E.oncomplete ();
      }
  

At this point we are very clear what the next thing, the nature of the entire process we will understand, so to sum up:

A closed loop is formed from left to right and then from right to left.
The end ...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.