Reactor one line of code high performance concurrent programming
Author: Research and Development-ouyang on the chain
Time: 2016-12-02
Response programming is a programming paradigm which is oriented to the change of data stream propagation. It is a best practice for observer patterns, iterator patterns, and functional programming. It simplifies the development of code through particularly complex low-level practices, so it is possible to perform high-performance concurrent programming for one line of code.
Suppose there is a requirement, a set of resource IDs have n, and each ID can be fetched to a resource with a network request. Need to get all the ID content.
Here's a simple simulation, look at the Concurrency code:
/**
* Parallel Execution
* @param concurrent Parallel Quantity
* @param sleeps simulation pause Time
* @return casually returned *
* Public iterator <String> list (int concurrent, Long ... sleeps) {return
Flux.fromarray (Sleeps)
. Flatmap (Sleep-> Mono.fromcallable (()-> mockhttp (Sleep)). Subscribeon (Schedulers.elastic ()), concurrent).
toiterable (). Iterator ();
}
This completes the execution of n-concurrency code, requiring only one line.
Dependency Packs
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core< /artifactid>
<version>3.0.2.RELEASE</version>
</dependency>
The complete test code is as follows:
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); /** * Random Test under * * @Test public void Concurrenttest () {//There is nothing to use here, pure schedulers.elastic () can reuse the thread pool here, Don't want to write much code. Flux.range (1,100). Map (a-> a*1). Subscribeon (Schedulers.elastic ()). Su
Bscribe ();
Start testing the long start = System.currenttimemillis (); The first parameter 20 20 concurrent//later represents n requests, the longest request may be 2000ms list (1000l,2000l,100l,200l,300l,400l,500l,600l,700l,800l,9
00l). foreachremaining (show-> logger.info);
Logger.info ("Total time: {} MS", System.currenttimemillis ()-start);
/** * Parallel Execution * @param concurrent Parallel quantity * @param sleeps simulation pause time * @return casually returned/public iterator<string> list (int concurrent, Long ... sleeps) {return flux.f Romarray (Sleeps). log (). Flatmap (Sleep-> mono.fromcallable (()-> mockhttp (Sleep)).
Subscribeon (Schedulers.elastic ()), concurrent). Toiterable (). iterator ();
/** * is actually an HTTP request * @param sleep Request time-consuming * @return/public String mockhttp (long sleep) {
try {thread.sleep (sleep);
Logger.info ("Pause {}ms really executed", sleep);
catch (Interruptedexception e) {e.printstacktrace ();
Return String.Format ("Paused%sms", sleep);
}
}
Look at the results of the execution:
17:10:59.663 [main] DEBUG reactor.util.loggers$loggerfactory-using slf4j logging Framework 17:10:59.748 [main] INFO REAC Tor. Flux.array.1-| Onsubscribe (REACTOR.CORE.PUBLISHER.FLUXARRAY$ARRAYSUBSCRIPTION@614DDD49) 17:10:59.750 [main] INFO reactor. Flux.array.1-| Request 17:10:59.750 [main] INFO reactor. Flux.array.1-| OnNext (1000) 17:10:59.811 [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.811) [main] INFO reactor. Flux.array.1-| OnNext (m) 17:10:59.811 [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.812) [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.812) [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.812) [main] INFO reactor. Flux.array.1-| OnNext (+) 17:10:59.812 [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.813) [main] INFO reactor. Flux.array.1-| OnNext (m) 17:10:59.813 [main] INFO reactor. Flux.array.1-| OnNext (17:10:59.813) [main] INFO reactor. Flux.array.1-| OnNext (900) 17:10:59.813 [main] INFO reactor. Flux.Array.1-|
OnComplete () 17:10:59.915 [elastic-4] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 100ms really executed 17:10:59.916 [elastic-4] INFO reactor. Flux.array.1-| Request (1) 17:10:59.918 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-paused 100ms 17:11:00.016 [ ELASTIC-5] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 200ms really executed 17:11:00.016 [elastic-5] Info reactor . Flux.array.1-| Request (1) 17:11:00.016 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-paused 200ms 17:11:00.116 [ ELASTIC-6] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 300ms really executed 17:11:00.116 [main] Info Com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 300ms 17:11:00.116 [elastic-6] INFO reactor. Flux.array.1-|
Request (1) 17:11:00.217 [elastic-7] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 400ms really executed 17:11:00.218 [elastic-7] INFO reactor. Flux.array.1-| Request (1) 17:11:00.219 [main] INFO Com.lianjia.sh.xcount.point.springmvc.ReactorTesT-paused 400ms 17:11:00.318 [elastic-8] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 500ms really executed 17:11:00.320 [elastic-8] INFO reactor. Flux.array.1-| Request (1) 17:11:00.320 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 500ms 17:11:00.417 [ ELASTIC-9] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 600ms really executed 17:11:00.418 [elastic-9] Info reactor . Flux.array.1-| Request (1) 17:11:00.419 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 600ms 17:11:00.516 [ ELASTIC-10] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 700ms really executed 17:11:00.518 [elastic-10] Info Reactor. Flux.array.1-| Request (1) 17:11:00.523 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 700ms 17:11:00.614 [ ELASTIC-11] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 800ms really executed 17:11:00.615 [elastic-11] Info Reactor. Flux.array.1-| Request (1) 17:11:00.616 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 800ms 17:11:00.724 [elastic-12] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 900ms really executed 17:11:00.724 [ Main] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-paused 900ms 17:11:00.724 [elastic-12] info reactor. Flux.array.1-|
Request (1) 17:11:00.815 [elastic-2] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 1000ms really executed 17:11:00.816 [Elastic-2] INFO reactor. Flux.array.1-| Request (1) 17:11:00.816 [main] INFO com.lianjia.sh.xcount.point.springmvc.ReactorTest-paused 1000ms 17:11:01.815 [ ELASTIC-3] Info com.lianjia.sh.xcount.point.springmvc.ReactorTest-Pause 2000ms really executed 17:11:01.835 [main] Info Com.lianjia.sh.xcount.point.springmvc.ReactorTest-Paused 2000ms 17:11:01.835 [main] INFO
Com.lianjia.sh.xcount.point.springmvc.ReactorTest-Total time: 2116 Ms Process finished with exit code 0