@@ -641,7 +641,7 @@ this.threadWorker就是刚才我们说的IoScheduler.CachedWorkerPool提供给Io
641641
642642#### 3.4.1 来一段非常非常simple的代码
643643
644- 先定义一个打印类,它内部可以持有一个其他的打印类source,在他的打印方法里会开启新线程执行source的打印方法
644+ 先定义一个打印类,它内部可以持有一个其他的打印类source,在他的打印方法里,如果source不为空,会开启新线程执行source的打印方法,如果source为空,这不开启新线程执行source的打印方法
645645
646646 private static class Printer {
647647 Printer source;
@@ -652,6 +652,10 @@ this.threadWorker就是刚才我们说的IoScheduler.CachedWorkerPool提供给Io
652652
653653 }
654654 void print() {
655+ if(source==null){
656+ System.out.println(name +"-"+ Thread.currentThread().getName());
657+ return;
658+ }
655659 new Thread(new Runnable() {
656660 @Override
657661 public void run() {
@@ -681,14 +685,12 @@ this.threadWorker就是刚才我们说的IoScheduler.CachedWorkerPool提供给Io
681685 printer4-Thread-0
682686 printer3-Thread-1
683687 printer2-Thread-2
684- printer1-Thread-3
688+ printer1-Thread-2
685689
686690
687691如果你清楚了这里要表示的这个原理,你可能就已经猜到为什么subscribeOn方法只有第一次指定线程的地方是有效的,我就不用费口舌了,文章到此结束。。。不过,那是不可能的,说好了要再装几分钟的x,怎么可能这么快。产品经理快扶我一把,虽然手断了,但我还要撸代码。
688692
689- 言归正传,这个原理是什么?对于任意一个Printer而言,不管外面包裹了多少层新的线程去调用他的print方法,他的print方法里的执行语句的工作线程永远都是他的print方法里new的那个Thread。那么在这里,对于第一个printer而言,不管你们把我传递了多少层,最后你们调用我的print方法的时候,我print方法里的执行语句的工作线程只能是我new的那个Thread。
690-
691- 类似如下代码
693+ 言归正传,这个原理是什么?对于任意一个Printer而言,不管外面包裹了多少个新的Printer去调用他的print方法,他的print方法里的执行语句的工作线程永远都是他下游的第一个Printer的print方法里new的那个Thread,因为第一个Printer的source为空,print方法里的输出语句就没有在被别的Thread包裹了。类似如下代码
692694
693695 new Thread(new Runnable() {
694696 @Override
@@ -708,7 +710,7 @@ this.threadWorker就是刚才我们说的IoScheduler.CachedWorkerPool提供给Io
708710 },"thread1").start();
709711
710712
711- Thread.currentThread().getName()的结果永远是thread3。清楚了这一点 ,我们就可以愉快的继续往下讲了。
713+ Thread.currentThread().getName()的结果永远是thread3。这里代码执行顺序和RxJava实际的顺序刚好相反,因为RxJava是逆向向上调用的,大家注意区分就好了。总之就是,第一个Printer的print方法的执行线程,只能是被他下游的Printer控制,到了这段代码里,那句输出语句打印出的线程名称,肯定是他外层Thread的名称。的清楚了这一点 ,我们就可以愉快的继续往下讲了。
712714
713715#### 3.4.2 Observable多次subscribeOn的流程类比
714716
@@ -729,68 +731,68 @@ Thread.currentThread().getName()的结果永远是thread3。清楚了这一点
729731
730732
731733 其次,定义一个Printer类来实现IPrinter接口
732-
733- private static class Printer implements IPrinter {
734+
735+ private static class Printer implements IPrinter {
734736 private IPrinter source;
735737 private String name;
736- private static volatile AtomicInteger createCount = new AtomicInteger(0);
737738
738- Printer(IPrinter source,String name) {
739+ Printer(IPrinter source, String name) {
739740 this.source = source;
740- this.name= name;
741+ this.name = name;
741742 }
742743
743744 @Override
744745 public void subscribe(IPaper paper) {
745- //这个地方非常关键
746- IPaper parent = new Paper(paper);
746+ //这个地方非常关键
747+ IPaper parent = new Paper(paper, name );
747748 preparePrint(parent);
748749 }
749750
750751 @Override
751752 public void preparePrint(IPaper paper) {
753+ System.out.println(name + " preparePrint on " +
754+ Thread.currentThread().getName());
755+ if (null == source) {
756+ print(paper);
757+ return;
758+ }
752759 new Thread(new Runnable() {
753760 @Override
754761 public void run() {
755- System.out.println("Printer-" + name + "-preparePrint-" +
756- Thread.currentThread().getName());
757762 if (null != source) {
758763 source.subscribe(paper);
759- } else {
760- print(paper);
761764 }
762765 }
763766 }).start();
764767 }
765768
766769 @Override
767770 public void print(IPaper paper) {
768- System.out.println("Printer-" + name + "-startPrint- " +
771+ System.out.println(name + " start print work on " +
769772 Thread.currentThread().getName());
770- paper.show();
773+ paper.show("哈哈哈哈哈" );
771774 }
772775 }
773-
776+
774777 再定义一个Paper类实现IPaper接口
775-
776- private static class Paper implements IPaper {
778+
779+ private static class Paper implements IPaper {
777780 private IPaper actual;
778- private static volatile AtomicInteger createCount = new AtomicInteger(0);
779- private int mId;
781+ private String printerName;
780782
781- Paper(IPaper actual) {
783+ Paper(IPaper actual,String printerName) {
784+ this.printerName=printerName;
782785 this.actual = actual;
783786 }
784787
785788 @Override
786- public void show() {
787- actual.show(content);
788- mId=createCount.incrementAndGet();
789- System.out.println("Paper-" + mId + "-show-" +
789+ public void show(String content) {
790+ System.out.println( printerName+" print on paper , and work on " +
790791 Thread.currentThread().getName());
792+ actual.show(content);
791793 }
792- }
793-
794+ }
795+
794796最后在main方法调用
795797
796798 public static void main(String args[]) {
@@ -800,24 +802,26 @@ Thread.currentThread().getName()的结果永远是thread3。清楚了这一点
800802 final IPrinter printer4 = new Printer(printer3, "printer4");
801803 printer4.subscribe(new IPaper() {
802804 @Override
803- public void show() {
804-
805+ public void show(String content) {
806+ System.out.println(content + " show on " +
807+ Thread.currentThread().getName());
805808 }
806809 });
807810 }
808811
809812
810813输出结果如下
811814
812- Printer-printer4-preparePrint-Thread-0
813- Printer-printer3-preparePrint-Thread-1
814- Printer-printer2-preparePrint-Thread-2
815- Printer-printer1-preparePrint-Thread-3
816- Printer-printer1-startPrint-Thread-3
817- Paper-1-show-Thread-3
818- Paper-2-show-Thread-3
819- Paper-3-show-Thread-3
820- Paper-4-show-Thread-3
815+ printer4 preparePrint on main//onSubscribe线程-main
816+ printer3 preparePrint on Thread-0//printer4 new的
817+ printer2 preparePrint on Thread-1//printer3 new的
818+ printer1 preparePrint on Thread-2//printer2 new的
819+ printer1 start print work on Thread-2
820+ printer1 print on paper , and work on Thread-2
821+ printer2 print on paper , and work on Thread-2
822+ printer3 print on paper , and work on Thread-2
823+ printer4 print on paper , and work on Thread-2
824+ 哈哈哈哈哈 show on Thread-2
821825
822826代码你们可以直接考出去运行的,看看我有没有说错。subscribeOn之所以只有第一次调用才有效,就是利用的类似这个demo展示的原理。顶层Observer发送数据的线程永远是第一次调用subscribeOn时指定的线程,因为数据的发射流程过程中,我们再也没有去切换过线程了,所以这其实很好理解的吧。
823827
0 commit comments