{"data":{"allMarkdownRemark":{"edges":[{"node":{"id":"19cc0c42-5288-55fa-abfe-4af1aeb242ca","frontmatter":{"category":"Engineering","title":"Rate Limiters and Thread blocking, is there an alternative?","date":"2022-07-18","summary":"There are some cases where you would like to limit the frequency that something happens to it work properly","thumbnail":null,"authorName":"Bruno Morais","authorDescription":"Bruno is a Senior Software Engineer at AUTO1 Group.","authorAvatar":{"relativePath":"pages/rate-limiters/avatar_Morais.jpeg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAQDAQX/xAAXAQEBAQEAAAAAAAAAAAAAAAABAwIE/9oADAMBAAIQAxAAAAGmbSadPSZMPIBLBy1//8QAHBAAAwABBQAAAAAAAAAAAAAAAQIDIQAQERIj/9oACAEBAAEFAqOVEql2047LLDc7A+i5H//EABcRAQEBAQAAAAAAAAAAAAAAAAEAEBL/2gAIAQMBAT8BC5jP/8QAGREAAwADAAAAAAAAAAAAAAAAAAECEBET/9oACAECAQE/AW9HSSsf/8QAGhAAAQUBAAAAAAAAAAAAAAAAAQACEBEhQf/aAAgBAQAGPwLBZRa4VFYt5Jj/xAAcEAADAAIDAQAAAAAAAAAAAAAAAREhURAxYXH/2gAIAQEAAT8ho6G+i0ElVBP0c6AzfMaH3OHLLoTIz//aAAwDAQACAAMAAAAQcC98/8QAGREAAwADAAAAAAAAAAAAAAAAABExEFGB/9oACAEDAQE/EGQbRPcf/8QAGxEAAgIDAQAAAAAAAAAAAAAAAAERMVFhscH/2gAIAQIBAT8QuM2dElucejs//8QAGxABAQEBAAMBAAAAAAAAAAAAAREAITFBYXH/2gAIAQEAAT8QEiRCoPrgpVComQJxnQidLcJrAFJfmh7Hwmff5oW4eD07h8orv//Z","width":50,"height":50,"src":"/static/7b4637bf5ab4eaf01facec045622cc5c/d2d31/avatar_Morais.jpeg","srcSet":"/static/7b4637bf5ab4eaf01facec045622cc5c/d2d31/avatar_Morais.jpeg 1x,\n/static/7b4637bf5ab4eaf01facec045622cc5c/0b804/avatar_Morais.jpeg 1.5x,\n/static/7b4637bf5ab4eaf01facec045622cc5c/753c3/avatar_Morais.jpeg 2x,\n/static/7b4637bf5ab4eaf01facec045622cc5c/31ca8/avatar_Morais.jpeg 3x"}}},"headerImage":{"relativePath":"pages/rate-limiters/header_Morais.jpg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUBAwT/xAAVAQEBAAAAAAAAAAAAAAAAAAABAP/aAAwDAQACEAMQAAABtzsIJMMhP//EABoQAAIDAQEAAAAAAAAAAAAAAAECAAMREBL/2gAIAQEAAQUCNWyxTnkdKrP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPwFX/8QAGRAAAwADAAAAAAAAAAAAAAAAAAExEBEh/9oACAEBAAY/AuM04TMP/8QAGhAAAgIDAAAAAAAAAAAAAAAAAAERYRAhUf/aAAgBAQABPyFTTBRag4ywx57U/9oADAMBAAIAAwAAABAfP//EABYRAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAwEBPxDZNb//xAAWEQEBAQAAAAAAAAAAAAAAAAAAARH/2gAIAQIBAT8QTD//xAAbEAEBAQEBAAMAAAAAAAAAAAABESEAUTFxsf/aAAgBAQABPxC+laoo/XnLJVVmzJ2YRT5s/eDOI4g51avPO//Z","width":1280,"height":849,"src":"/static/d7fdf1093c10ccf7ff201925fb486d79/966a5/header_Morais.jpg","srcSet":"/static/d7fdf1093c10ccf7ff201925fb486d79/966a5/header_Morais.jpg 1x,\n/static/d7fdf1093c10ccf7ff201925fb486d79/aa36d/header_Morais.jpg 1.5x"}}}},"html":"<p>Let's talk about harmony! If you have a look at an English dictionary, you'll see that even though almost everyone has some knowledge of the meaning of the word harmony, it's not so simple to properly define it. There are many contexts that it may apply, such as people relationships, business, law, and so on.</p>\n<p>But, at the end of the day, this concept imported from the music means that something happens in a way or frequency that makes it pleasant and less error-prone. So I want you to focus on the idea that the proper frequency is a way to achieve harmony.</p>\n<p>There are some cases where you would like to limit the frequency that something happens to it work properly. Imagine that you have a coffee machine, it's obvious that you would like it to dispense coffee at a frequency that you can replace the cups and be able to serve all your guests.</p>\n<p>It happens everywhere, even on software. At least while we have limited resources, we have to orchestrate them to work in harmony. One strategy is to use Rate Limiters, a maneuver to control the frequency in which some action is handled.</p>\n<h2>Rate Limiters</h2>\n<p>A common pattern to achieve the Rate Limiter strategy is to use the Token Bucket algorithm. In a nutshell, the Token Bucket mimics a real bucket where Theme Park tickets are stored. To enter to play around at the Theme Park, you need to take a ticket. But if the bucket is empty, you have to wait until some new tickets are put in there. Doing like that, you become able to control the flow of people to the Theme Park by controlling the number of tickets that are put into the bucket and the time interval in which the refill occurs.</p>\n<p>If we put 10 tickets per minute on that bucket, it'll assure that at most 10 people will enter the Theme Park in each 1-minute interval.</p>\n<p>Libraries like Google Guava, Resilience4j, and Bucket4j are examples of how we can achieve rate-limiting in our Java software.</p>\n<p>Despite being a beta version by the time of this writing, using the Google Guava RateLimiter library is pretty straightforward. You create a RateLimiter object defining the number of permits per second and, for each task, you specify that it should \"acquire\" the token that allows it to proceed.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">final</span> <span class=\"token class-name\">RateLimiter</span> rateLimiter <span class=\"token operator\">=</span> <span class=\"token class-name\">RateLimiter</span><span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token number\">2.0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// rate is \"2 permits per second\"</span>\n    <span class=\"token keyword\">void</span>  <span class=\"token function\">submitTasks</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span> tasks<span class=\"token punctuation\">,</span> <span class=\"token class-name\">Executor</span> executor<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">Runnable</span> task <span class=\"token operator\">:</span> tasks<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        rateLimiter<span class=\"token punctuation\">.</span><span class=\"token function\">acquire</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// may wait</span>\n        executor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span>task<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>For Resilience4J you need to create some configuration before and decorate your task:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"> <span class=\"token comment\">// Create a custom RateLimiter configuration</span>\n<span class=\"token class-name\">RateLimiterConfig</span> config <span class=\"token operator\">=</span> <span class=\"token class-name\">RateLimiterConfig</span><span class=\"token punctuation\">.</span><span class=\"token function\">custom</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">timeoutDuration</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Duration</span><span class=\"token punctuation\">.</span><span class=\"token function\">ofMillis</span><span class=\"token punctuation\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">limitRefreshPeriod</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Duration</span><span class=\"token punctuation\">.</span><span class=\"token function\">ofSeconds</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">limitForPeriod</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// Create a RateLimiter</span>\n<span class=\"token class-name\">RateLimiter</span> rateLimiter <span class=\"token operator\">=</span> <span class=\"token class-name\">RateLimiter</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token string\">\"backendName\"</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token punctuation\">,</span> config<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// Decorate your call to BackendService.doSomething()</span>\n<span class=\"token class-name\">Supplier</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> restrictedSupplier <span class=\"token operator\">=</span> <span class=\"token class-name\">RateLimiter</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">decorateSupplier</span><span class=\"token punctuation\">(</span>rateLimiter<span class=\"token punctuation\">,</span> backendService<span class=\"token operator\">::</span><span class=\"token function\">doSomething</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// First call is successful</span>\n<span class=\"token class-name\">Try</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> firstTry <span class=\"token operator\">=</span> <span class=\"token class-name\">Try</span><span class=\"token punctuation\">.</span><span class=\"token function\">ofSupplier</span><span class=\"token punctuation\">(</span>restrictedSupplier<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>firstTry<span class=\"token punctuation\">.</span><span class=\"token function\">isSuccess</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">isTrue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>In the same path, now using Bucket4j, you need to specify the refill interval and the limit:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token class-name\">Refill</span> refill <span class=\"token operator\">=</span> <span class=\"token class-name\">Refill</span><span class=\"token punctuation\">.</span><span class=\"token function\">intervally</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Duration</span><span class=\"token punctuation\">.</span><span class=\"token function\">ofSeconds</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token class-name\">Bandwidth</span> limit <span class=\"token operator\">=</span> <span class=\"token class-name\">Bandwidth</span><span class=\"token punctuation\">.</span><span class=\"token function\">classic</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> refill<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token class-name\">Bucket</span> bucket <span class=\"token operator\">=</span> <span class=\"token class-name\">Bucket4j</span><span class=\"token punctuation\">.</span><span class=\"token function\">builder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">addLimit</span><span class=\"token punctuation\">(</span>limit<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">.</span><span class=\"token function\">tryConsume</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    executor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span>task<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>But if you want that the employees from the theme park's main entrance do other tasks while the customers are in the queue and still not allowed to enter, I mean if you want that your thread is used for other tasks, at least these 3 libraries have a pattern that may be a problem to you: they block the thread.</p>\n<h2>Thread Blocking</h2>\n<p>Now we are in the second part of this article, and as we are talking about Threads, it's good to know some basics about them. The first step is to know that they allow us to work concurrently, two tasks running virtually at the same time. But Threads are notoriously complex and error-prone, inaugurating a new sorts of problems like Deadlock, Race Condition, and so on.</p>\n<p>As we said at the start of this article, considering that we have limited resources, we have to use Threads with wisdom and be as clever as possible.</p>\n<p>If I and my wife are in the kitchen and we have just one knife available, it is appropriate that once one of us stop using the knife we leave it available to the other over the table, so that the other could start working with this piece of cutlery.</p>\n<p>When one forgets about this rule, the other one is kept waiting for the tool, and important work is not held, preventing the flow of a harmonious cuisine.</p>\n<p>The computer environment works like this kitchen, we have a limited number of Threads. And when something blocks one thread with a Thread.sleep() or LockSupport.parkNanos(), this Thread goes to the TIMED_WAITING state and during this time it can not be used. It is like the unused knife in the cooker's hand of an unharmonious kitchen.</p>\n<p>In practical terms, consider the following code:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">guavaRateLimiter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token class-name\">RateLimiter</span> rateLimiter <span class=\"token operator\">=</span> <span class=\"token class-name\">RateLimiter</span><span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">logWithThreadTimeStamped</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token class-name\">IntStream</span><span class=\"token punctuation\">.</span><span class=\"token function\">rangeClosed</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n    rateLimiter<span class=\"token punctuation\">.</span><span class=\"token function\">acquire</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logWithThreadTimeStamped</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Task n. \"</span> <span class=\"token operator\">+</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">logWithThreadTimeStamped</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm blocked =(\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">logWithThreadTimeStamped</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>It will output as follow:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">[12:01:31.972073] Starting Thread: main\n[12:01:31.978520] Task n. 1 Thread: main\n[12:01:32.471752] Task n. 2 Thread: main\n[12:01:32.967231] Task n. 3 Thread: main\n[12:01:33.470331] Task n. 4 Thread: main\n[12:01:33.470662] I'm blocked =( Thread: main\n[12:01:33.470845] Finishing Thread: main</code></pre></div>\n<p>What we wanted was that our 4 tasks were completed in a frequency of at most 2 for each second, but the Rate Limiter also has blocked the other tasks.</p>\n<p>You may ask, what to do? Perhaps, we should schedule instead of blocking!</p>\n<h2>Scheduling</h2>\n<p>Imagine when you need to go to the doctor. Unless there is an emergency, you will likely have to make an appointment. The schedules are spread in a timeline, considering the doctor's ability to do the entire checkup: anamnesis, some additional exams, and so on. So to say, if the doctor takes an average of 30 minutes to attend to a patient appointment, those appointments should be guaranteed in intervals of 30 minutes.</p>\n<p>With this in mind, we could refactor our previous code. If we need that our tasks are executed at a rate of 2 per second, it means that we should schedule our tasks for every 500 milliseconds, which is one second (1000 milliseconds) divided by 2.</p>\n<p>Now that we know our interval, we have to find a way to keep track of our \"appointments\", to avoid scheduling more than one task to the same interval. Let's use an AtomicInteger class for that.</p>\n<p>Let's scratch some code:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">taskScheduling</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token keyword\">var</span> scheduleExecutor <span class=\"token operator\">=</span> <span class=\"token class-name\">Executors</span><span class=\"token punctuation\">.</span><span class=\"token function\">newSingleThreadScheduledExecutor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> intervalDiary <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">AtomicInteger</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> expectedInterval <span class=\"token operator\">=</span> <span class=\"token number\">500</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token class-name\">IntStream</span><span class=\"token punctuation\">.</span><span class=\"token function\">rangeClosed</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n    scheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">schedule</span><span class=\"token punctuation\">(</span>\n        <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Task n. \"</span> <span class=\"token operator\">+</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        intervalDiary<span class=\"token punctuation\">.</span><span class=\"token function\">getAndAdd</span><span class=\"token punctuation\">(</span>expectedInterval<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm NOT blocked =D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> message<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">println</span><span class=\"token punctuation\">(</span>message <span class=\"token operator\">+</span> <span class=\"token string\">\" Thread: \"</span> <span class=\"token operator\">+</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">.</span><span class=\"token function\">currentThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>It will output as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Starting - Thread: main\nI'm NOT blocked =D Thread: main\nFinishing - Thread: main\nTask n. 1 - Thread: pool-1-thread-1\nTask n. 2 - Thread: pool-1-thread-1\nTask n. 3 - Thread: pool-1-thread-1\nTask n. 4 - Thread: pool-1-thread-1</code></pre></div>\n<p>Oh, it worked, but seems like we are cheating, because we just added a new thread to the game. How can we know for sure if that new thread is not being blocked? Well, we can test it like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">taskSchedulingV2</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token keyword\">var</span> scheduleExecutor <span class=\"token operator\">=</span> <span class=\"token class-name\">Executors</span><span class=\"token punctuation\">.</span><span class=\"token function\">newSingleThreadScheduledExecutor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> intervalDiary <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">AtomicInteger</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> expectedInterval <span class=\"token operator\">=</span> <span class=\"token number\">500</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token class-name\">IntStream</span><span class=\"token punctuation\">.</span><span class=\"token function\">rangeClosed</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n    scheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">schedule</span><span class=\"token punctuation\">(</span>\n        <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Task n. \"</span> <span class=\"token operator\">+</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        intervalDiary<span class=\"token punctuation\">.</span><span class=\"token function\">getAndAdd</span><span class=\"token punctuation\">(</span>expectedInterval<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm NOT blocked =D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And voilà:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Starting Thread: pool-1-thread-1\nTask n. 1 Thread: pool-1-thread-1\nI'm NOT blocked =D Thread: pool-1-thread-1\nFinishing Thread: pool-1-thread-1\nTask n. 2 Thread: pool-1-thread-1\nTask n. 3 Thread: pool-1-thread-1\nTask n. 4 Thread: pool-1-thread-1</code></pre></div>\n<p>The downside of this approach is that the ScheduledExecutorService, that we receive from the newSingleThreadScheduledExecutor() method of the Executors class, uses an unbounded queue. This means that no task will ever be rejected (by the meaning of the unbounded word, it is like an unlimited queue), and because of that, we have the risk of consuming too much memory if we receive tasks more quickly than we can handle them.</p>\n<p>Of course, we can avoid that in many ways. One approach could be to track the number of scheduled tasks and reject new tasks if we hit the specified threshold. First of all, let's refactor our code so that we use a queue of tasks as the source to be used by the scheduler.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">taskSchedulingV3</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token keyword\">var</span> scheduleExecutor <span class=\"token operator\">=</span> <span class=\"token class-name\">Executors</span><span class=\"token punctuation\">.</span><span class=\"token function\">newSingleThreadScheduledExecutor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> myTasks <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> EXPECTED_INTERVAL <span class=\"token operator\">=</span> <span class=\"token number\">500</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">scheduleAtFixedRate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span>\n    <span class=\"token function\">ofNullable</span><span class=\"token punctuation\">(</span>myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">poll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">ifPresent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Runnable</span><span class=\"token operator\">::</span><span class=\"token function\">run</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> EXPECTED_INTERVAL<span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token class-name\">IntStream</span><span class=\"token punctuation\">.</span><span class=\"token function\">rangeClosed</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">-></span>\n    myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Task n.\"</span> <span class=\"token operator\">+</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm NOT blocked =D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Our log:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Starting Thread: pool-1-thread-1\nTask n.1 Thread: pool-1-thread-1\nI'm NOT blocked =D Thread: pool-1-thread-1\nFinishing Thread: pool-1-thread-1\nTask n.2 Thread: pool-1-thread-1\nTask n.3 Thread: pool-1-thread-1\nTask n.4 Thread: pool-1-thread-1</code></pre></div>\n<p>Now in this version, we are using the scheduleAtFixedRate() method, which frees us from keeping track of the already used intervals. It now checks for new tasks for every expected interval.</p>\n<p>But what would happen if we have more tasks coming than we are able to handle? The following code creates a new task for each 250ms but handles new tasks just in an interval of 500ms.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span>  <span class=\"token keyword\">void</span>  <span class=\"token function\">taskSchedulingOverload</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token keyword\">var</span> scheduleExecutor <span class=\"token operator\">=</span> <span class=\"token class-name\">Executors</span><span class=\"token punctuation\">.</span><span class=\"token function\">newSingleThreadScheduledExecutor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> myTasks <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> EXPECTED_INTERVAL <span class=\"token operator\">=</span> <span class=\"token number\">500</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> SMALLER_INTERVAL <span class=\"token operator\">=</span> <span class=\"token number\">250</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">scheduleAtFixedRate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span>\n    <span class=\"token function\">ofNullable</span><span class=\"token punctuation\">(</span>myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">poll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">ifPresent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Runnable</span><span class=\"token operator\">::</span><span class=\"token function\">run</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> EXPECTED_INTERVAL<span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">scheduleAtFixedRate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span>\n    myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Fast Task! Task lasting: \"</span> <span class=\"token operator\">+</span> myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> SMALLER_INTERVAL<span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm NOT blocked =D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Our output would be something like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Starting Thread: pool-1-thread-1\nI'm NOT blocked =D Thread: pool-1-thread-1\nFinishing Thread: pool-1-thread-1\nFast Task! Task lasting: 1 Thread: pool-1-thread-1\nFast Task! Task lasting: 2 Thread: pool-1-thread-1\nFast Task! Task lasting: 3 Thread: pool-1-thread-1\nFast Task! Task lasting: 4 Thread: pool-1-thread-1\nFast Task! Task lasting: 5 Thread: pool-1-thread-1\nFast Task! Task lasting: 6 Thread: pool-1-thread-1\nFast Task! Task lasting: 7 Thread: pool-1-thread-1\nFast Task! Task lasting: 8 Thread: pool-1-thread-1\nFast Task! Task lasting: 9 Thread: pool-1-thread-1\n\n(...)</code></pre></div>\n<p>The size of the queue will not stop raising, leading us to an out-of-memory error. Oh, but don't be so afraid my friend, as we said we can limit the schedule based on that queue. Like if you call the doctor to make an appointment and they answer you: \"sorry, for the next 10 years all our schedules are already taken, please call in another day (or year).\"</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span>  <span class=\"token keyword\">void</span>  <span class=\"token function\">taskSchedulingLimitingByQueueSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token keyword\">var</span> scheduleExecutor <span class=\"token operator\">=</span> <span class=\"token class-name\">Executors</span><span class=\"token punctuation\">.</span><span class=\"token function\">newSingleThreadScheduledExecutor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> myTasks <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> EXPECTED_INTERVAL <span class=\"token operator\">=</span> <span class=\"token number\">500</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> SMALLER_INTERVAL <span class=\"token operator\">=</span> <span class=\"token number\">250</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> QUEUE_LIMIT <span class=\"token operator\">=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Starting\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">scheduleAtFixedRate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span>\n    <span class=\"token function\">ofNullable</span><span class=\"token punctuation\">(</span>myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">poll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">ifPresent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Runnable</span><span class=\"token operator\">::</span><span class=\"token function\">run</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> EXPECTED_INTERVAL<span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">scheduleAtFixedRate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> QUEUE_LIMIT<span class=\"token punctuation\">)</span>\n        myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Fast Task! Task lasting: \"</span> <span class=\"token operator\">+</span> myTasks<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span>\n        <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I was rejected =(\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> SMALLER_INTERVAL<span class=\"token punctuation\">,</span> <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"I'm NOT blocked =D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nscheduleExecutor<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">logWithThread</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Finishing\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Our output:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Starting Thread: pool-1-thread-1\nI'm NOT blocked =D Thread: pool-1-thread-1\nFinishing Thread: pool-1-thread-1\nFast Task! Task lasting: 1 Thread: pool-1-thread-1\nFast Task! Task lasting: 2 Thread: pool-1-thread-1\nFast Task! Task lasting: 3 Thread: pool-1-thread-1\nI was rejected =( Thread: pool-1-thread-1\nFast Task! Task lasting: 3 Thread: pool-1-thread-1\nI was rejected =( Thread: pool-1-thread-1\nFast Task! Task lasting: 3 Thread: pool-1-thread-1\nI was rejected =( Thread: pool-1-thread-1\nFast Task! Task lasting: 3 Thread: pool-1-thread-1</code></pre></div>\n<p>Here we have to talk about backpressure. Remember that this problem about memory only occurs if always the input of tasks is faster than the output. If the input of tasks was faster in just a point of time, this surplus of tasks will be kept on the queue and properly handled in the following time. So with this approach, our application could control the rate of events so that fast producers (sending new tasks) does not overwhelm our consumer.</p>\n<p>In a blocking approach, the producer will be forced to wait. In the scheduling approach, the new tasks will be handled in time, and only if it overloads that some of them will be queued.</p>\n<p>You could say, but how long should be my queue? Well, I may say that it depends on your use case. A doctor could have a schedule book for all the current year. And if it shows to be not enough, the doctor can buy a new schedule book for the next year. As in your application service, if you can afford more memory, your queues can be as long as you want.</p>\n<p>But in the case of a traveling circus, if it will be in the town for just 3 weeks it doesn't make sense to accept schedules for the next month. The same as your application, if its capacity of handling tasks isn't fast enough at a point that the handling of an older schedule task starts to become unmeaningful, you should shrink your queue.</p>\n<h2>Conclusion</h2>\n<p>We can conclude that scheduling is a good approach for rate-limiting without the downside of blocking the thread. It gives us the opportunity of controlling the flow of incoming tasks, queueing peaks, and always handle the tasks in harmony with all other components.</p>","fields":{"slug":"/rate-limiters/","tags":["auto1","engineering","RateLimiter","Thread","Scheduling"]}}}]}},"pageContext":{"slug":"/tags/RateLimiter","tag":"RateLimiter","categories":["Architecture","Coding","DevOps","Engineering","ProjectManagement","QA","Social","TechRadar"]}}