在下面的示例代码中,我正在尝试从远程source1和远程source2获取 - 这两者都需要来自远程source0的输入。我想从source0只取一次AND source from source1& source2同时。
$query = "SELECT firstname FROM users WHERE id = '17'";
$query_run = mysql_query($query);
$row = mysql_fetch_row($query_run);
echo $row[0];
此输出显示Source1和Source2未并行获取:
public class TestReactiveX5 {
public static void main(String[] args) throws Exception {
Scheduler scheduler = Schedulers.io();
RemoteSourceData<Integer, Integer> source0 = new RemoteSource0();
RemoteSourceData<Integer, String> source1 = new RemoteSource1();
RemoteSourceData<Integer, String> source2 = new RemoteSource2();
Observable<Integer> i = Observable.just(1);
Observable<Integer> i0 = i.map(input -> source0.getData(input)).share();
Observable<String> fooSource = i0.map(input0 -> source1.getData(input0)).subscribeOn(scheduler);
Observable<String> barSource = i0.map(input0 -> source2.getData(input0)).subscribeOn(scheduler);
Observable<List<String>> merged = Observable.merge(fooSource, barSource).toList();
merged.subscribe(val -> System.out.println(val));
Thread.sleep(15000);
}
@FunctionalInterface
private static interface RemoteSourceData<IN, OUT> {
public OUT getData(IN input);
}
public static class RemoteSource0 implements RemoteSourceData<Integer, Integer> {
@Override
public Integer getData(Integer input) {
try {
System.out.println("fetch from remote Source0 " + new Timestamp(System.currentTimeMillis()));
Thread.sleep(2000L);
} catch (InterruptedException ex) {
// ignore
}
return 0;
}
}
private static class RemoteSource1 implements RemoteSourceData<Integer, String> {
@Override
public String getData(Integer i) {
try {
System.out.println("fetch from remote Source1 " + new Timestamp(System.currentTimeMillis()));
Thread.sleep(4000L);
} catch (InterruptedException ex) {
// ignore
}
return "foo";
}
}
private static class RemoteSource2 implements RemoteSourceData<Integer, String> {
@Override
public String getData(Integer i) {
try {
System.out.println("fetch from remote Source2 " + new Timestamp(System.currentTimeMillis()));
Thread.sleep(4000L);
} catch (InterruptedException ex) {
// ignore
}
return "bar";
}
}
}
如果删除share(),则Source1和Source2并行获取,但需要两次调用Source0:
fetch from remote Source0 2016-06-03 16:00:38.802
fetch from remote Source2 2016-06-03 16:00:40.803
fetch from remote Source1 2016-06-03 16:00:44.804
[bar, foo]
如何调用Source0和并行调用Source1&amp;源2?
答案 0 :(得分:0)
并没有并行查询源,因为它们使用相同的线程,您可以在不同来源的操作之间进行休眠。
我添加了一些额外的日志记录来显示基本示例的执行线程:
从远程获取Source0 2016-06-03 23:28:35.426 Thread = Thread [RxIoScheduler-2,5,main] 从远程Source1获取2016-06-03 23:28:37.426 Thread = Thread [RxIoScheduler-2,5,main] 从远程获取Source2 2016-06-03 23:28:41.426 Thread = Thread [RxIoScheduler-2,5,main] [foo,bar]
正如您所看到的,对于预期会睡2秒和4秒的所有任务来说,它是相同的线程。
我尝试了subscribeOn
和observeOn
的不同配置,并且不能说它对我来说是完全透明的,为什么RxJava在某些情况下会做它的功能,但这里有一些东西,为我工作:
public static void main(String[] args) throws Exception {
Scheduler scheduler = Schedulers.io();
RemoteSourceData<Integer, Integer> source0 = new RemoteSource0();
RemoteSourceData<Integer, String> source1 = new RemoteSource1();
RemoteSourceData<Integer, String> source2 = new RemoteSource2();
Observable<Integer> i = Observable.just(1).subscribeOn(scheduler);
Observable<Integer> i0 = i.map(source0::getData).share();
Observable<String> fooSource = i0.observeOn(scheduler).map(source1::getData);
Observable<String> barSource = i0.observeOn(scheduler).map(source2::getData);
Observable<List<String>> merged = Observable.merge(fooSource, barSource).toList();
merged.subscribe(System.out::println);
Thread.sleep(15000);
}
输出:
从远程获取Source0 2016-06-03 23:37:11.264 Thread = Thread [RxIoScheduler-3,5,main] 从远程Source1获取2016-06-03 23:37:13.265 Thread = Thread [RxIoScheduler-2,5,main] 从远程Source2获取2016-06-03 23:37:13.265 Thread = Thread [RxIoScheduler-4,5,main] [foo,bar]
现在fooSource
和barSource
各有专用线程并且并行运行。