{"id":59782,"date":"2020-08-18T11:49:44","date_gmt":"2020-08-18T11:49:44","guid":{"rendered":"https:\/\/www.baeldung.com\/?p=85851"},"modified":"2020-08-18T11:49:44","modified_gmt":"2020-08-18T11:49:44","slug":"concurrency-in-spring-webflux","status":"publish","type":"post","link":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/2020\/08\/18\/concurrency-in-spring-webflux\/","title":{"rendered":"Concurrency in Spring WebFlux"},"content":{"rendered":"<p class=\"syndicated-attribution\"><meta name= \\\"keywords \\\" content= \\\"\u96fb\u5b50\u8a08\u7b97\u6a5f, \u6559\u80b2, IT \u96fb\u8166\u73ed,\u96fb\u8166\u88dc\u7fd2\uff0c \u96fb\u8166\u73ed\uff0c \u5bb6\u6559\uff0c \u79c1\u4eba\u8001\u5e2b\uff0c \u8cc7\u8a0a\u6280\u8853\uff0c \u7a0b\u5e8f\u8a2d\u8a08\uff0c \u96fb\u5b50\u8a08\u7b97\u6a5f\uff0c \u904a\u6232\uff0c \u860b\u679c\uff0c \u96fb\u5f71\uff0c \u8a08\u7b97\u6a5f\uff0c\u7de8\u78bc\uff0c Java\uff0c C\/C++\uff0c JavaScript\uff0c PHP\uff0c HTML\uff0c CSS\uff0c MySQL\uff0c mobile\uff0c Android\uff0c \u52d5\u6f2b\uff0c Python\uff0c teacher\uff0c \u88dc\u7fd2\uff0c \u96fb\u8166\u88dc\u7fd2 \u8cc7\u8a0a, \u7535\u5b50\u8ba1\u7b97\u673a, IT ,Game, apple, movie, Computer,student,Java,\u6559\u80b2, ,\u5b66\u751f, \u5b66\u4e60, learn, \u6559\u5b66,  Android, apple,anime, animation, \u4fe1\u606f\u6280\u672f, \u7a0b\u5e8f\u8bbe\u8ba1, \u79fb\u52a8\u7535\u8bdd, \u8cc7\u8a0a\u79d1\u6280,Game, Jeu, Juego,Call Of Duty ,\u4f7f\u547d\u53ec\u559a , \u6e38\u620f, \u7535\u5b50\u6e38\u620f,, \u591a\u4eba\u7535\u5b50\u6e38\u620f, \u7f51\u7edc\u6e38\u620f\uff0conline\uff0conline game, \u624b\u673a\u6e38\u620f, mobile \\\"><\/p>\n<h2  data-id=\"introduction-2\">1. Introduction<\/h2>\n<div class=\"bd-anchor\" id=\"introduction-2\"><\/div>\n<p>In this tutorial, we&#8217;ll explore concurrency in reactive programs written with <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/docs.spring.io\/spring\/docs\/current\/spring-framework-reference\/web-reactive.html\">Spring WebFlux<\/a>.<\/p>\n<p>We&#8217;ll begin by discussing concurrency in relation to reactive programming. After that, we&#8217;ll explore how Spring WebFlux offers concurrency abstractions over different reactive server libraries.<\/p>\n<h2  data-id=\"the_motivation_for_reactive_programming\">2. The Motivation for Reactive Programming<\/h2>\n<div class=\"bd-anchor\" id=\"the_motivation_for_reactive_programming\"><\/div>\n<p>A typical <strong>web application comprises of several complex, interacting parts<\/strong>. <strong>Many of these interactions are blocking in nature<\/strong> like, for example, those involving a database call to fetch or update data.\u00a0 <strong>Several others, however, are independent and can be performed concurrently,<\/strong> possibly in parallel.<\/p>\n<p><strong>For instance, two user requests to a web server can be handled by different threads.<\/strong> On a <em>multi-core <\/em>platform, this has an obvious benefit in terms of the overall response time. Hence, <strong>this model of concurrency is known as the<em> thread-per-request model<\/em><\/strong>:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85863 size-full\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model.jpg\" alt=\"\" width=\"867\" height=\"327\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model.jpg 867w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model-300x113.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model-768x290.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Thread-per-Request-Model-100x38.jpg 100w\" sizes=\"(max-width: 867px) 100vw, 867px\" \/><\/a><\/p>\n<p>In the diagram above, each thread handles a single request at a time.<\/p>\n<p>While thread-based concurrency solves a part of the problem for us, it does nothing to address the fact that <strong>most of our interactions within a single thread are still blocking<\/strong>. Moreover, the native threads we use to achieve concurrency in Java come at a significant cost in terms of context switches.<\/p>\n<p>Meanwhile, as web applications face more and more requests, <strong>the <em>thread-per-request model<\/em> starts to fall short of expectations<\/strong>.<\/p>\n<p>Consequently, <strong>what we need is a concurrency model which can help us handle increasingly more requests with relatively less number of threads<\/strong>. <strong>This is one of the primary motivations for adopting <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-reactive-systems\">reactive programing<\/a>.<\/strong><\/p>\n<h2  data-id=\"concurrency_in_reactive_programming\">3. Concurrency in Reactive Programming<\/h2>\n<div class=\"bd-anchor\" id=\"concurrency_in_reactive_programming\"><\/div>\n<p><strong>Reactive programming helps us structure the program in terms of data flows and the propagation of change through them<\/strong>. Hence, in a completely non-blocking environment, this can enable us to achieve higher concurrency with better resource utilization.<\/p>\n<p>However, is reactive programming a complete departure from thread-based concurrency? While this is a strong statement to make, <strong>reactive programming certainly has a very different approach to the usage of threads to achieve concurrency<\/strong>. So, <strong>the fundamental difference that reactive programming brings on is asynchronicity.<\/strong><\/p>\n<p>In other words, the program flow transforms from a sequence of synchronous operations, into an asynchronous stream of events.<\/p>\n<p>For instance, under the reactive model, a read call to the database does not block the calling thread while data is fetched. The <strong>call immediately returns a publisher that others can subscribe to<\/strong>. The subscriber can process the event after it occurs and may even further generate events itself:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85861 size-full\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model.jpg\" alt=\"\" width=\"864\" height=\"320\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model.jpg 864w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model-300x111.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model-768x284.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Reactive-Model-100x37.jpg 100w\" sizes=\"(max-width: 864px) 100vw, 864px\" \/><\/a><\/p>\n<p>Above all, reactive programming does not emphasize on which thread events should be generated and consumed. <strong>Emphasis is, rather, on structuring the program as an asynchronous event stream<\/strong>.<\/p>\n<p>The publisher and subscriber here do not need to be part of the same thread. <strong>This helps us in getting better utilization of available threads and hence higher overall concurrency.<\/strong><\/p>\n<h2  data-id=\"event_loop\">4. Event Loop<\/h2>\n<div class=\"bd-anchor\" id=\"event_loop\"><\/div>\n<p><strong>There are several programming models that describe a reactive approach to concurrency<\/strong>.<\/p>\n<p>In this section, we&#8217;ll examine a few of them to understand how reactive programming achieves higher concurrency with fewer threads.<\/p>\n<p><strong>One of such reactive asynchronous programming model for servers is the <em>event loop<\/em> <em>model<\/em><\/strong>:<\/p>\n<figure class=\"wp-block-image size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85859 size-full\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop.jpg\" alt=\"\" width=\"1024\" height=\"362\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop.jpg 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop-300x106.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop-768x272.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Event-Loop-100x35.jpg 100w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>Above, is an abstract design of an <em>event loop <\/em>that presents the ideas of reactive asynchronous programming:<\/p>\n<ul>\n<li><strong>The<em> event loop<\/em> runs continuously in a single thread<\/strong>, although we can have as many<em> event loops<\/em> as the number of available cores<\/li>\n<li><strong>The<em> event loop<\/em> process the events from an <em>event queue<\/em> sequentially and returns immediately<\/strong> after registering the <em>callback<\/em> with the <em>platform<\/em><\/li>\n<li>The <em>platform<\/em> can trigger the completion of an operation like a database call or an external service invocation<\/li>\n<li><strong>The <em>event loop<\/em> can trigger the <em>callback<\/em> on the <em>operation completion<\/em> notification and send back the result to the original caller<\/strong><\/li>\n<\/ul>\n<p>The <em>event loop<\/em> <em>model<\/em> is implemented in a number of platforms including <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/nodejs.org\/en\/\">Node.js<\/a><\/em>, <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/netty.io\/\">Netty<\/a><\/em>, and <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.nginx.com\/\">Ngnix<\/a><\/em>. They offer much better scalability than traditional platforms like <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/httpd.apache.org\/\">Apache HTTP Server<\/a><\/em>, <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/tomcat\">Tomcat<\/a><\/em>, or <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.redhat.com\/fr\/technologies\/jboss-middleware\/application-platform\">JBoss<\/a><\/em>.<\/p>\n<h2  data-id=\"reactive_programming_with_spring_webflux\">5. Reactive Programming with Spring WebFlux<\/h2>\n<div class=\"bd-anchor\" id=\"reactive_programming_with_spring_webflux\"><\/div>\n<p>Now, we have enough insights into reactive programming and its concurrency model, to explore the subject in Spring WebFlux.<\/p>\n<p><strong>WebFlux is<\/strong> <b>the <\/b><strong style=\"font-weight: bold\">Spring<\/strong><strong>&#8216;s<\/strong> <strong>reactive-stack web framework<\/strong>, which was added in version 5.0.<\/p>\n<p>Let&#8217;s explore the server-side stack of Spring WebFlux to understand how it complements the traditional web stack in Spring:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Spring-Web-Stack.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85862 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Spring-Web-Stack.jpg\" alt=\"\" width=\"605\" height=\"333\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Spring-Web-Stack.jpg 670w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Spring-Web-Stack-300x165.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Spring-Web-Stack-100x55.jpg 100w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<p>As we can see, <strong>Spring WebFlux sits parallel to the traditional web framework in Spring and does not necessarily replace it<\/strong>.<\/p>\n<p>There are a few important points to note here:<\/p>\n<ul>\n<li>Spring WebFlux extends the traditional annotation-based programming model with functional routing<\/li>\n<li>Moreover, it adapts the underlying HTTP runtimes to the <em>Reactive Streams API<\/em> making the runtimes interoperable<\/li>\n<li>Hence, it&#8217;s able to support a wide variety of reactive runtimes including Servlet 3.1+ containers like Tomcat, Reactor, Netty, or <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/jboss-undertow\">Undertow<\/a><\/li>\n<li>Lastly, it includes <em>WebClient<\/em>, a reactive and non-blocking client for HTTP requests offering functional and fluent APIs<\/li>\n<\/ul>\n<h2  data-id=\"threading_model_in_supported_runtimes\">6. Threading Model in Supported Runtimes<\/h2>\n<div class=\"bd-anchor\" id=\"threading_model_in_supported_runtimes\"><\/div>\n<p>As we have discussed earlier, <strong>reactive programs tend to work with just a few threads<\/strong> and make the most of them. However, the number and nature of threads depend upon the actual Reactive Stream API runtime that we choose.<\/p>\n<p>To clarify, <strong>Spring WebFlux can adapt to different runtimes through a common API provided by <em>HttpHandler<\/em><\/strong>. This API is a simple contract with just one method that provides an abstraction over different server APIs like Reactor Netty, Servlet 3.1 API, or Undertow APIs.<\/p>\n<p>Let&#8217;s now understand the threading model implemented in a few of them.<\/p>\n<p><strong>While Netty is the default server in a WebFlux application, it&#8217;s just a matter of declaring the right dependency to switch to any other supported server<\/strong>:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-webflux&lt;\/artifactId&gt;\r\n    &lt;exclusions&gt;\r\n        &lt;exclusion&gt;\r\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;spring-boot-starter-reactor-netty&lt;\/artifactId&gt;\r\n        &lt;\/exclusion&gt;\r\n    &lt;\/exclusions&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-tomcat&lt;\/artifactId&gt;\r\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>While it&#8217;s possible to observe the threads created in a Java Virtual Machine in a number of ways, it&#8217;s quite easy just to pull them from the <em>Thread<\/em> class itself:<\/p>\n<pre><code class=\"language-java\">Thread.getAllStackTraces()\r\n  .keySet()\r\n  .stream()\r\n  .collect(Collectors.toList());<\/code><\/pre>\n<h3 data-id=\"1-reactor-netty\">6.1. Reactor Netty<\/h3>\n<div class=\"bd-anchor\" id=\"1-reactor-netty\"><\/div>\n<p>As we said, <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/netty.io\/\">Reactor Netty<\/a> is the default embedded server in the Spring Boot WebFlux starter. Let&#8217;s try to see the threads that Netty creates by default. Hence, in the beginning, we&#8217;ll not add any other dependencies or use WebClient. So, if we start a Spring WebFlux application created using its SpringBoot starter, we can expect to see some default threads it creates:<\/p>\n<figure class=\"aligncenter size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85853 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1.jpg\" alt=\"\" width=\"676\" height=\"300\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1.jpg 881w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1-300x133.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1-768x341.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/1-100x44.jpg 100w\" sizes=\"(max-width: 676px) 100vw, 676px\" \/><\/a><\/p>\n<p>Note that, apart from a normal thread for the server,<strong> Netty spawns a bunch of worker threads for request processing<\/strong>. <strong>These typically are not more than available CPU cores.<\/strong> This is the output on a quad-core machine. We&#8217;d also see a bunch of housekeeping threads typical to a JVM environment, but they are not important here.<\/p>\n<p><strong>Netty uses the event loop model to provide highly scalable concurrency in a reactive asynchronous manner.<\/strong> Let&#8217;s see how Netty implements event loop <strong>levering Java NIO to provide this scalability<\/strong>:<\/p>\n<figure class=\"wp-block-image size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85860 size-full\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model.jpg\" alt=\"\" width=\"842\" height=\"331\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model.jpg 842w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model-300x118.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model-768x302.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Netty-Threading-Model-100x39.jpg 100w\" sizes=\"(max-width: 842px) 100vw, 842px\" \/><\/a><\/p>\n<p>Here, <strong><em>EventLoopGroup <\/em>manages one or more <em>EventLoop<\/em> which must be continuously running<\/strong>. Hence, <strong>it&#8217;s not recommended to create more <em>EventLoops<\/em>\u00a0than the number of available cores.<\/strong><\/p>\n<p>The <em>EventLoopGroup <\/em>further assigns an <em>EventLoop <\/em>to each newly created <em>Channel<\/em>. Thus, for the lifetime of a <em>Channel<\/em>, all operations are executed by the same thread.<\/p>\n<h3 data-id=\"2-apache-tomcat\">6.2. Apache Tomcat<\/h3>\n<div class=\"bd-anchor\" id=\"2-apache-tomcat\"><\/div>\n<p><strong>Spring WebFlux is also supported on a traditional Servlet Container like <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~tomcat.apache.org\/\">Apache Tomcat<\/a>.<\/strong><\/p>\n<p><strong>WebFlux relies on the Servlet 3.1 API with non-blocking I\/O<\/strong>. While it uses Servlet API behind a low-level adapter, Servlet API is not available for direct usage.<\/p>\n<p>Let&#8217;s see what kind of threads we expect in a WebFlux application running on Tomcat:<\/p>\n<figure class=\"aligncenter size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85854 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1.jpg\" alt=\"\" width=\"505\" height=\"615\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1.jpg 841w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1-246x300.jpg 246w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1-768x935.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/2-841x1024-1-100x122.jpg 100w\" sizes=\"(max-width: 505px) 100vw, 505px\" \/><\/a><\/p>\n<p>The number and type of threads which we can see here are quite different from what we observed earlier.<\/p>\n<p>To begin with, <strong>Tomcat starts with more worker threads, which defaults to ten<\/strong>. Of course, we&#8217;ll also see some housekeeping threads typical to the JVM, and the Catalina container, which we can ignore for this discussion.<\/p>\n<p>Let&#8217;s understand the architecture of Tomcat with Java NIO to correlate it with the threads we see above.<\/p>\n<p><strong>Tomcat 5 onward supports NIO in its Connector component, which is primarily responsible for receiving the requests<\/strong>.<\/p>\n<p>The other Tomcat component is the Container component, which is responsible for the container management functions.<\/p>\n<p>The point of interest for us here is the threading model that the Connector component implements to support NIO. It is comprised of <em>Acceptor<\/em>, <em>Poller, <\/em>and <em>Worker <\/em>as part of the <em>NioEndpoint<\/em> module:<\/p>\n<figure class=\"wp-block-image size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85864 size-full\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector.jpg\" alt=\"\" width=\"953\" height=\"253\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector.jpg 953w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector-300x80.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector-768x204.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/Tomcat-NIO-Connector-100x27.jpg 100w\" sizes=\"(max-width: 953px) 100vw, 953px\" \/><\/a><\/p>\n<p><strong>Tomcat spawns one or more threads for <em>Acceptor<\/em>, <em>Poller<\/em>, and <em>Worker<\/em> with typically a thread pool dedicated to <em>Worker<\/em><\/strong>.<\/p>\n<p>While a detailed discussion on Tomcat architecture is beyond the scope of this tutorial, we should now have enough insights to understand the threads we saw earlier.<\/p>\n<h2  data-id=\"threading_model_in_webclient\">7. Threading Model in <em>WebClient<\/em><\/h2>\n<div class=\"bd-anchor\" id=\"threading_model_in_webclient\"><\/div>\n<p><strong><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-5-webclient\"><em>WebClient<\/em><\/a> <\/strong>is <strong>the reactive HTTP client that is part of Spring WebFlux<\/strong>. We can use it anytime we require REST-based communication and enables us to create applications that are <em>end-to-end<\/em> <em>reactive<\/em>.<\/p>\n<p>As we have seen before, reactive applications work with just a few threads, and so, there is no margin for any part of the application to block a thread. Hence, <em>WebClient<\/em> plays a vital role in helping us realize the potential of WebFlux.<\/p>\n<h3 data-id=\"1-using-webclient\">7.1. Using <em>WebClient<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"1-using-webclient\"><\/div>\n<p>Using <em>WebClient<\/em> is quite simple as well. <strong>We do not need to include any specific dependencies as it&#8217;s part of Spring WebFlux<\/strong>.<\/p>\n<p>Let&#8217;s create a simple REST endpoint which returns a <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-string-from-mono\"><em>Mono<\/em><\/a>:<\/p>\n<pre><code class=\"language-java\">@GetMapping(\"\/index\")\r\npublic Mono&lt;String&gt; getIndex() {\r\n    return Mono.just(\"Hello World!\");\r\n}<\/code><\/pre>\n<p>Then, we&#8217;ll use <em>WebClient<\/em> to call this REST endpoint and consume the data reactively:<\/p>\n<pre><code class=\"language-java\">WebClient.create(\"http:\/\/localhost:8080\/index\").get()\r\n  .retrieve()\r\n  .bodyToMono(String.class)\r\n  .doOnNext(s -&gt; printThreads());<\/code><\/pre>\n<p>Here, we&#8217;re also printing the threads that are created using the method we discussed earlier.<\/p>\n<h3 data-id=\"2-understanding-the-threading-model\">7.2. Understanding the Threading Model<\/h3>\n<div class=\"bd-anchor\" id=\"2-understanding-the-threading-model\"><\/div>\n<p>So, how does the threading model work in the case of <em>WebClient<\/em>?<\/p>\n<p>Well, not surprisingly, <strong><em>WebClient<\/em> also implements concurrency using the <em>event loop model<\/em><\/strong>. Of course, it relies on the underlying runtime to provide the necessary infrastructure.<\/p>\n<p><strong>If we&#8217;re running <em>WebClient<\/em> on the Reactor Netty, it shares the event loop that Netty uses for the server<\/strong>. Hence, in this case, we may not notice much difference in the threads that are created.<\/p>\n<p>However, <strong><em>WebClient<\/em> is also supported on a Servlet 3.1+ container like Jetty, but the way it works there is different<\/strong>.<\/p>\n<p>If we compare the threads that are created on a WebFlux application running <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.eclipse.org\/jetty\/\">Jetty<\/a> with and without <em>WebClient<\/em>, we&#8217;ll notice a few additional threads.<\/p>\n<p>Here, <em>WebClient<\/em> has to create its <em>event loop<\/em>. So, we can see a fixed number of processing threads that this event loop creates:<\/p>\n<figure class=\"aligncenter size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85855 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3.jpg\" alt=\"\" width=\"535\" height=\"400\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3.jpg 876w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3-300x224.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3-768x574.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/3-100x75.jpg 100w\" sizes=\"(max-width: 535px) 100vw, 535px\" \/><\/a><\/p>\n<p><strong>In some cases,<\/strong> <strong>having a separate thread pool for client and server can provide better performance<\/strong>. While it&#8217;s not the default behavior with Netty, it&#8217;s always possible to declare a dedicated thread pool for <em>WebClient<\/em> if needed.<\/p>\n<p>We&#8217;ll see how this is possible in a later section.<\/p>\n<h2  data-id=\"threading_model_in_data_access_libraries\">8. Threading Model in Data Access Libraries<\/h2>\n<div class=\"bd-anchor\" id=\"threading_model_in_data_access_libraries\"><\/div>\n<p>As we have seen earlier, <strong>even a simple application usually consists of several parts that need to be connected.<\/strong><\/p>\n<p>Typical examples of these parts include databases and message brokers. <strong>The existing libraries to connect with many of them are still blocking, but that is changing fast.<\/strong><\/p>\n<p><strong>There are several databases now that offer reactive libraries for connectivity<\/strong>. <strong>Many of these libraries are available within <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-data\">Spring Data<\/a><\/strong>, while we can use others directly as well.<\/p>\n<p>The threading model these libraries use is of particular interest to us.<\/p>\n<h3 data-id=\"1-spring-data-mongodb\">8.1. Spring Data MongoDB<\/h3>\n<div class=\"bd-anchor\" id=\"1-spring-data-mongodb\"><\/div>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-data-mongodb-tutorial\">Spring Data MongoDB<\/a> provides reactive repository support for MongoDB built on top of the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~mongodb.github.io\/mongo-java-driver\/\">MongoDB Reactive Streams driver<\/a>. Most notably, this driver <strong>fully implements the Reactive Streams API to provide asynchronous stream processing<\/strong> with <em>non-blocking back-pressure<\/em>.<\/p>\n<p>Setting up support for the reactive repository for MongoDB in a Spring Boot application is as simple as adding a dependency:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-data-mongodb-reactive&lt;\/artifactId&gt;\r\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>This will allow us to create a repository, and use it to perform some basic operations on MongoDB in a non-blocking manner:<\/p>\n<pre><code class=\"language-java\">public interface PersonRepository extends ReactiveMongoRepository&lt;Person, ObjectId&gt; {\r\n}\r\n.....\r\npersonRepository.findAll().doOnComplete(this::printThreads);<\/code><\/pre>\n<p>So, what kind of threads can we expect to see when we run this application on the Netty server?<\/p>\n<p>Well, not surprisingly, we&#8217;ll not see much difference as <strong>a<\/strong> <strong>Spring Data reactive repository makes use of the same event loop that is available for the server.<\/strong><\/p>\n<h3 data-id=\"2-reactor-kafka\">8.2. Reactor Kafka<\/h3>\n<div class=\"bd-anchor\" id=\"2-reactor-kafka\"><\/div>\n<p><strong>Spring is still in the process of building full-fledged support for reactive Kafka.<\/strong> However, we do have options available outside Spring.<\/p>\n<p><strong><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/projectreactor.io\/docs\/kafka\/release\/reference\/#_introduction\">Reactor Kafka<\/a> is a reactive API for Kafka based on Reactor<\/strong>. Reactor Kafka enables messages to be published and consumed using functional APIs, also with <em>non-blocking back-pressure<\/em>.<\/p>\n<p>First, we need to add the required dependency in our application to start using Reactor Kafka:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;io.projectreactor.kafka&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;reactor-kafka&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.2.2.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>This should enable us to produce messages to Kafka in a non-blocking manner:<\/p>\n<pre><code class=\"language-java\">\/\/ producerProps: Map of Standard Kafka Producer Configurations\r\nSenderOptions&lt;Integer, String&gt; senderOptions = SenderOptions.create(producerProps);\r\nKafkaSender&lt;Integer, String&gt; sender =  KafkaSender.create(senderOptions);\r\nFlux&lt;SenderRecord&lt;Integer, String, Integer&gt;&gt; outboundFlux = Flux\r\n  .range(1, 10)\r\n  .map(i -&gt; SenderRecord.create(new ProducerRecord&lt;&gt;(\"reactive-test\", i, \"Message_\" + i), i));\r\nsender.send(outboundFlux).subscribe();<\/code><\/pre>\n<p>Similarly, we should be able to consume messages from Kafka, also, in a non-blocking manner:<\/p>\n<pre><code class=\"language-java\">\/\/ consumerProps: Map of Standard Kafka Consumer Configurations\r\nReceiverOptions&lt;Integer, String&gt; receiverOptions = ReceiverOptions.create(consumerProps);\r\nreceiverOptions.subscription(Collections.singleton(\"reactive-test\"));\r\nKafkaReceiver&lt;Integer, String&gt; receiver = KafkaReceiver.create(receiverOptions);\r\nFlux&lt;ReceiverRecord&lt;Integer, String&gt;&gt; inboundFlux = receiver.receive();\r\ninboundFlux.doOnComplete(this::printThreads)<\/code><\/pre>\n<p>This is pretty simple and self-explanatory.<\/p>\n<p>We&#8217;re subscribing to a topic <em>reactive-test<\/em> in Kafka and getting a <em>Flux <\/em>of messages.<\/p>\n<p>The <strong>interesting thing for us is the threads that get created<\/strong>:<\/p>\n<figure class=\"aligncenter size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85856 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4.jpg\" alt=\"\" width=\"554\" height=\"313\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4.jpg 874w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4-300x170.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4-768x434.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/4-100x57.jpg 100w\" sizes=\"(max-width: 554px) 100vw, 554px\" \/><\/a><\/p>\n<p><strong>We can see a few threads that are not typical to the Netty server<\/strong>.<\/p>\n<p>This indicates that Reactor Kafka manages its own thread pool, with a few worker threads, that participate in Kafka message processing exclusively. Of course, we&#8217;ll see a bunch of other threads related to Netty and the JVM that we can ignore.<\/p>\n<p><strong>Kafka producers use a separate network thread for sending requests to the broker.<\/strong> Further, they deliver responses to the application on a <em>single-threaded pooled scheduler<\/em>.<\/p>\n<p>Kafka consumer, on the other hand, has one thread per consumer group &#8211; that blocks to listen for incoming messages. The incoming messages are then scheduled for processing on a different thread pool.<\/p>\n<h2  data-id=\"scheduling_options_in_webflux\">9. Scheduling Options in WebFlux<\/h2>\n<div class=\"bd-anchor\" id=\"scheduling_options_in_webflux\"><\/div>\n<p>We have seen so far that <strong>reactive programming really shines in a completely non-blocking environment with just a few threads<\/strong>. But, this also means that, if there is indeed a part that is blocking, it will result in far worse performance. This is because a blocking operation can freeze the event loop entirely.<\/p>\n<p>So,<strong> how do we handle long-running processes or blocking operations in reactive programming?<\/strong><\/p>\n<p>Honestly, the best option would be just to avoid them. However, this may not be always possible, and <strong>we may need a dedicated scheduling strategy for those parts of our application<\/strong>.<\/p>\n<p>Spring WebFlux <strong>offers a mechanism to switch processing to a different thread pool in between a data flow chain<\/strong>. This can provide us precise control over the scheduling strategy that we want for certain tasks. Of course, <em>WebFlux<\/em> is able to offer this based on the thread pool abstractions, known as schedulers, available in the underlying reactive libraries.<\/p>\n<h3 data-id=\"1-reactor\">9.1. Reactor<\/h3>\n<div class=\"bd-anchor\" id=\"1-reactor\"><\/div>\n<p>In <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/projectreactor.io\/\">Reactor<\/a>, the <strong><em>Scheduler<\/em> class defines the execution model as well as where the execution takes place<\/strong>.<\/p>\n<p>The <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/projectreactor.io\/docs\/core\/release\/api\/reactor\/core\/scheduler\/Schedulers.html.\">Schedulers<\/a><\/em> class provides a number of execution contexts like <em>immediate<\/em>, <em>single<\/em>, <em>elastic<\/em>, and <em>parallel<\/em>.<\/p>\n<p>These provide different types of thread pools which can be useful for different jobs. Moreover, we can always create our own <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/projectreactor.io\/docs\/core\/release\/api\/reactor\/core\/scheduler\/Scheduler.html\"><em>Scheduler <\/em><\/a>with a preexisting <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/ExecutorService.html\"><em>ExecutorService<\/em><\/a>.<\/p>\n<p>While <em>Schedulers <\/em>gives us several execution contexts, Reactor <strong>also provides us different ways to switch the execution context<\/strong>. They are the methods <em>publishOn <\/em>and <em>subscribeOn<\/em>.<\/p>\n<p>We can use <em>publishOn <\/em>with a <em>Scheduler <\/em>anywhere in the chain, with that <em>Scheduler<\/em> affecting all the subsequent operators.<\/p>\n<p>While we can also use <em>subscribeOn <\/em>with a <em>Scheduler <\/em>anywhere in the chain, it will only affect the context of the source of emission.<\/p>\n<p>If we recall, <em>WebClient<\/em> on Netty shares the same<em> event loop<\/em> created for the server as a default behavior. However, we may have valid reasons to create a dedicated thread pool for WebClient.<\/p>\n<p>Let&#8217;s see how we can achieve this in Reactor which is the default reactive library in WebFlux:<\/p>\n<pre><code class=\"language-java\">Scheduler scheduler = Schedulers.newBoundedElastic(5, 10, \"MyThreadGroup\");\r\nWebClient.create(\"http:\/\/localhost:8080\/index\").get()\r\n  .retrieve()\r\n  .bodyToMono(String.class)\r\n  .publishOn(scheduler)\r\n  .doOnNext(s -&gt; printThreads());<\/code><\/pre>\n<p>Earlier, we did not observe any difference in the threads created on Netty with or without <em>WebClient<\/em>. However, if we now run the code above, <strong>we&#8217;ll observe a few new threads being created<\/strong>:<\/p>\n<figure class=\"aligncenter size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85857 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5.jpg\" alt=\"\" width=\"546\" height=\"153\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5.jpg 874w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5-300x84.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5-768x215.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/5-100x28.jpg 100w\" sizes=\"(max-width: 546px) 100vw, 546px\" \/><\/a><\/p>\n<p>Here, <strong>we can see the threads created as part of our <em>bounded elastic thread pool<\/em><\/strong>. It is where responses from the <em>WebClient<\/em> are published once subscribed.<\/p>\n<p>This leaves the main thread pool for handling the server requests.<\/p>\n<h3 data-id=\"2-rxjava\">9.2. RxJava<\/h3>\n<div class=\"bd-anchor\" id=\"2-rxjava\"><\/div>\n<p>The <strong>default behavior in RxJava is not very different than that of Reactor<\/strong>.<\/p>\n<p>The <em>Observable<\/em>, and the chain of operators we apply on it, do their work &#8211; and notify the observers &#8211; on the same thread where the subscription was invoked. Also, <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/github.com\/ReactiveX\/RxJava\">RxJava<\/a>, like Reactor, offers ways to introduce prefixed or custom scheduling strategies into the chain.<\/p>\n<p>RxJava also <strong>features a class <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~reactivex.io\/RxJava\/javadoc\/io\/reactivex\/schedulers\/Schedulers.html\">Schedulers<\/a>, <\/em>which offers a number of execution models for the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~reactivex.io\/RxJava\/javadoc\/io\/reactivex\/Observable.html\"><em>Observable <\/em><\/a>chain<\/strong>. These include <em>new thread<\/em>, <em>immediate<\/em>, <em>trampoline<\/em>, <em>io<\/em>, <em>computation<\/em>, and <em>test<\/em>. Of course, it also allows us to define a <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~reactivex.io\/documentation\/scheduler.html\">Scheduler<\/a> <\/em>from a Java <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/Executor.html\"><em>Executor<\/em><\/a>.<\/p>\n<p>Moreover, RxJava also <strong>offers two extension methods to achieve this<\/strong>, <em>subscribeOn<\/em> and<em> observeOn<\/em>.<\/p>\n<p>The <em>subscribeOn <\/em>method changes the default behavior by specifying a different <em>Scheduler<\/em> on which <em>Observable <\/em>should operate.<\/p>\n<p>The <em>observeOn <\/em>method, on the other hand, specifies a different Scheduler that the <em>Observable<\/em> can use to send notifications to the observers.<\/p>\n<p>As we have discussed before Spring WebFlux uses Reactor as its reactive library by default. But, since it&#8217;s fully compatible with Reactive Streams API, it&#8217;s <strong>possible to switch to another Reactive Streams implementation like RxJava<\/strong> (for RxJava 1.x with its Reactive Streams adapter).<\/p>\n<p>We need to explicitly add the dependency:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;io.reactivex.rxjava2&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;rxjava&lt;\/artifactId&gt;\r\n    &lt;version&gt;2.2.19&lt;\/version&gt;\r\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>Then, we can start to use RxJava types like <em>Observable <\/em>in our application along with RxJava specific <em>Schedulers<\/em>:<\/p>\n<pre><code class=\"language-java\">io.reactivex.Observable\r\n    .fromIterable(Arrays.asList(\"Tom\", \"Sawyer\"))\r\n    .map(s -&gt; s.toUpperCase())\r\n    .observeOn(io.reactivex.schedulers.Schedulers.trampoline())\r\n    .doOnComplete(this::printThreads);<\/code><\/pre>\n<p>As a result, if we run this application, apart from the regular Netty and JVM related threads <strong>we should see a few threads related to our RxJava <em>Scheduler<\/em><\/strong>:<\/p>\n<figure class=\"wp-block-image size-large\"><\/figure>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-85858 \" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6.jpg\" alt=\"\" width=\"543\" height=\"153\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6.jpg 871w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6-300x84.jpg 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6-768x216.jpg 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/08\/6-100x28.jpg 100w\" sizes=\"(max-width: 543px) 100vw, 543px\" \/><\/a><\/p>\n<h2  data-id=\"conclusion-8\">10. Conclusion<\/h2>\n<div class=\"bd-anchor\" id=\"conclusion-8\"><\/div>\n<p>In this article, we explored the premise of reactive programming from the context of concurrency.<\/p>\n<p>We observed the difference in the concurrency model in traditional and reactive programming. This allowed us to examine the concurrency model in Spring WebFlux, and its take on the threading model to achieve it.<\/p>\n<p>Further, we explored the threading model in WebFlux in combination with different HTTP runtime and reactive libraries.<\/p>\n<p>We also discussed how the threading model differs when we use <em>WebClient<\/em> or a data access library.<\/p>\n<p>Lastly, we touched upon the options for controlling the scheduling strategy in our reactive program within WebFlux.<\/p>\n<p>As always, the source code for this article can be found <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/github.com\/eugenp\/tutorials\/tree\/master\/spring-webflux-threads\">over on GitHub<\/a>.<\/p>\n<p><Img align=\"left\" border=\"0\" height=\"1\" width=\"1\" alt=\"\" style=\"border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;\" hspace=\"0\" src=\"https:\/\/feeds.feedblitz.com\/~\/i\/633827297\/0\/baeldung\"><\/p>\n<div style=\"clear:both;padding-top:0.2em;\"><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Share on Google+\" href=\"https:\/\/feeds.feedblitz.com\/_\/30\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/googleplus20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/633827297\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2020%2F08%2FThread-per-Request-Model.jpg\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/spring-webflux-concurrency#respond\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>&#160;<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/spring-webflux-concurrency\/feed\/\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>&#160;<\/div>\n\n<p class=\"syndicated-attribution\"><figure class= \\\"wp-block-image alignnone \\\"><img src= \\\"http:\/\/itteacheritfreelance.hk\/test\/wordpress\/wp-content\/uploads\/2016\/05\/logo2-2.png\\\" alt=\\\"IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\\\"\/><figcaption>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427!<\/figcaption><\/figure>\r\n<\/br>Find A Teacher Form:\r\n<\/br>https:\/\/docs.google.com\/forms\/d\/1vREBnX5n262umf4wU5U2pyTwvk9O-JrAgblA-wH9GFQ\/viewform?edit_requested=true#responses\r\n<\/br><\/br>Email:\r\n<\/br>public1989two@gmail.com<br><br><br><br><br><br><br>\r\n<a href=www.itsec.hk style=color:#FFFFFF;>www.itsec.hk<\/a><br>\r\n<a href=\\\"www.itsec.vip\\\" style=color:#FFFFFF;>www.itsec.vip<\/a><br>\r\n<a href=\\\"www.itseceu.uk\\\" style=color:#FFFFFF;>www.itseceu.uk<\/a><br><\/p>","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>Concurrency in Spring Webflux depends on many factors. Let&#8217;s explore them in-depth.<\/p>\n<div><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\"><\/a>&nbsp;<a title=\"Share on Google+\" href=\"https:\/\/feeds.feedblitz.com\/_\/30\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/googleplus20.png\"><\/a>&nbsp;<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/633827297\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2020%2F08%2FThread-per-Request-Model.jpg\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\"><\/a>&nbsp;<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\"><\/a>&nbsp;<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\"><\/a>&nbsp;<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/633827297\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\"><\/a>&nbsp;<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/spring-webflux-concurrency#respond\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>&nbsp;<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/spring-webflux-concurrency\/feed\/\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>&nbsp;<\/div>\n<\/div>","protected":false},"author":762,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"slim_seo":{"title":"Concurrency in Spring WebFlux - ITTeacherITFreelance.hk","description":"Concurrency in Spring Webflux depends on many factors. Let's explore them in-depth. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"},"footnotes":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/59782"}],"collection":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/762"}],"replies":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=59782"}],"version-history":[{"count":3,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/59782\/revisions"}],"predecessor-version":[{"id":61563,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/59782\/revisions\/61563"}],"wp:attachment":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=59782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=59782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=59782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}