reactor一行代码高性能并发编程
作者:链上研发-ouyang
时间:2016-12-02
响应式编程是一种面向数据流传播改变的编程范式。它是观察者模式、迭代器模式和函数式编程的一种最佳实践。它通过特别复杂的底层实践来简化开发的代码,所以才有可能进行一行代码的高性能并发编程。
假设有一个需求,有一组资源ID有n个,每个ID都可以用个网络请求获取到资源。需要获取所有的ID内容。
这里简单模拟下,看看并发代码:
/**
* 并行执行
* @param concurrent 并行数量
* @param sleeps 模拟停顿时间
* @return 随便返回了
*/
public Iterator<String> list(int concurrent, Long... sleeps){
return Flux.fromArray(sleeps)
.flatMap(sleep -> Mono.fromCallable( () -> mockHttp(sleep)).subscribeOn(Schedulers.elastic()), concurrent)
.toIterable().iterator();
}
这样就完成了一个执行n个并发的代码,仅仅需要一行。
依赖包
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
完整的测试代码如下:
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class ReactorTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ReactorTest.class);
/**
* 随便测试下
*/
@Test
public void concurrentTest(){
//这里没有什么用,纯粹是Schedulers.elastic()可以复用这里的线程池,不想写多的代码了
Flux.range(1,100).map(a -> a*1)
.subscribeOn(Schedulers.elastic())
.subscribe();
//开始测试了
long start = System.currentTimeMillis();
//第一个参数20 20个并发
//后面表示N个请求,最长的一个请求可能要2000ms
list(20, 1000l,2000l,100l,200l,300l,400l,500l,600l,700l,800l,900l)
.forEachRemaining( show -> LOGGER.info(show) );
LOGGER.info("总时间 : {} ms", System.currentTimeMillis() - start );
}
/**
* 并行执行
* @param concurrent 并行数量
* @param sleeps 模拟停顿时间
* @return 随便返回了
*/
public Iterator<String> list(int concurrent, Long... sleeps){
return Flux.fromArray(sleeps)
.log()
.flatMap(sleep -> Mono.fromCallable( () -> mockHttp(sleep)).subscribeOn(Schedulers.elastic()), concurrent)
.toIterable().iterator();
}
/**
* 实际上是一个http请求
* @param sleep 请求耗时
* @return