title: Round robin scheduling algorithm in Java using AtomicBoolean
body: <p>I want to implement a strict round robin scheduling when i send requests to an external system. There are two external system servers. The first request should go to 'System1' and the second request must go to 'System2' and next one to 'System1' and so on.</p>
  
  <p>Since i have only two servers to send the request to, and since i want maximum performance without any blocking and context switch, i have gone for AtomicBoolean since it makes use of CAS operation. </p>
  
  <p>My implementation classes</p>
  
  <p><strong>1. RoundRobinTest.java</strong></p>
  
  <pre><code>package com.concurrency;
  
  import java.util.Iterator;
  
  public class RoundRobinTest 
  {
      public static void main(String[] args) 
      {
          for (int i = 0; i &lt; 500; i++) 
          {
              new Thread(new RoundRobinLogic()).start();
          }
          try 
          {
              // Giving a few seconds for the threads to complete
              Thread.currentThread().sleep(2000);
              Iterator&lt;String&gt; output = RoundRobinLogic.output.iterator();
              int i=0;
              while (output.hasNext()) 
              {
                  System.out.println(i+++":"+output.next());
                  // Sleeping after each out.print 
                  Thread.currentThread().sleep(20);
              }
          } 
          catch (Exception ex) 
          {
              // do nothing
          }
      }
  
  }
  </code></pre>
  
  <p><strong>2.RoundRobinLogic.java</strong>(Class with static AtomicBoolean object)</p>
  
  <pre><code>package com.concurrency;
  
  import java.util.Queue;
  import java.util.concurrent.ConcurrentLinkedDeque;
  import java.util.concurrent.atomic.AtomicBoolean;
  
  public class RoundRobinLogic implements Runnable 
  {
      private static AtomicBoolean bool = new AtomicBoolean(true);
  
      public static Queue&lt;String&gt; output = new ConcurrentLinkedDeque&lt;&gt;();
  
      @Override
      public void run() 
      {
          if(bool.getAndSet(false))
          {
              // Sending the request to first system
              output.add("Request to System1");
          }
          else if(!bool.getAndSet(true))
          {
              // Sending the request to first system
              output.add("Request to System2");
          }       
      }
  
  }
  </code></pre>
  
  <p><strong>Output:</strong></p>
  
  <hr>
  
  <pre><code>......................
  314:Request to System1
  315:Request to System2
  316:Request to System1
  317:Request to System2
  318:Request to System1
  319:Request to System1
  320:Request to System2
  321:Request to System2
  322:Request to System1
  323:Request to System2
  324:Request to System1
  325:Request to System2
  ......................
  </code></pre>
  
  <hr>
  
  <p>The requests 318 and 319 had been sent to the same server and AtomicBoolean fails in this scenario. For my application 1000-2000 threads might be accessing the shared object at a time.
  From Java concurrency in practice, i have seen the below.</p>
  
  <p><em>at high contention levels locking tends to outperform atomic variables, but at more realistic
  contention levels atomic variables outperform locks. This is because a lock reacts to contention by suspending threads,
  reducing CPU usage and synchronization traffic on the shared memory bus.</em> 
  <em>With low to moderate contention, atomics offer better scalability; with high contention, locks offer 
  better  contention  avoidance.  (CAS based  algorithms  also  outperform  lock based  ones on  single CPU  systems,  since  a 
  CAS always succeeds on a single CPU system except in the unlikely case that a thread is preempted in the middle of the 
  read modify write operation.)</em> </p>
  
  <p><strong>Now i have the below questions.</strong></p>
  
  <ol>
  <li>Is there any other efficient non-blocking way, to achieve the round-robin request sending.</li>
  <li>Under heavy contention, is it possible for the AtomicBoolean to fail ? What i understand is that performance/throughput might go down due to heavy contention. But in the above example AtomicBoolean fails . Why ? </li>
  </ol>