Java和Round-Robin上的AtomicInteger

AtomicInteger属于Atomic Variables族。 主要好处是使用它不会阻塞而不是进行阻塞同步,因此避免了线程的挂起和重新调度。

AtomicInteger基于“比较和交换”机制,并且是原子变量的标量组的一部分。

我们的第一个用例是可以多次访问的网页上的功能。

 package com.gkatzioura.concurrency;  import java.util.concurrent.atomic.AtomicInteger;  public class AtomicIntegerExample { 
     private AtomicInteger atomicInteger = new AtomicInteger(); 
     public void serveRequest() { 
         atomicInteger.incrementAndGet(); 
         /** 
          * logic 
          */ 
     } 
     public int requestsServed() { 
         return atomicInteger.get(); 
     }  } 

并测试我们的用例

 package com.gkatzioura.concurrency;  import java.util.ArrayList;  import java.util.List;  import java.util.concurrent.ExecutionException;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.Future;  import org.junit.jupiter.api.Assertions;  import org.junit.jupiter.api.BeforeEach;  import org.junit.jupiter.api.Test;  public class AtomicIntegerExampleTest { 
     private AtomicIntegerExample atomicIntegerExample; 
     @BeforeEach 
     void setUp() { 
         atomicIntegerExample = new AtomicIntegerExample(); 
     } 
     @Test 
     void testConcurrentIncrementAndGet() throws ExecutionException, InterruptedException { 
         final int threads = 10 ; 
         ExecutorService executorService = Executors.newFixedThreadPool(threads); 
         List<Future> futures = new ArrayList(); 
         for ( int i = 0 ; i { 
                 atomicIntegerExample.serveRequest(); 
                 return null ; 
             })); 
         } 
         for (Future future: futures) { 
             future.get(); 
         } 
         Assertions.assertEquals( 10 ,atomicIntegerExample.requestsServed()); 
     }  } 

除了使用原子整数作为计数器之外,您还可以在各种情况下使用它。 例如线程安全的循环算法。

 package com.gkatzioura.concurrency;  import java.util.concurrent.atomic.AtomicInteger;  public class AtomicIntegerRoundRobin { 
     private final int totalIndexes; 
     private final AtomicInteger atomicInteger = new AtomicInteger(- 1 ); 
     public AtomicIntegerRoundRobin( int totalIndexes) { 
         this .totalIndexes = totalIndexes; 
     } 
     public int index() { 
         int currentIndex; 
         int nextIndex; 
         do { 
             currentIndex = atomicInteger.get(); 
             nextIndex = currentIndex< Integer.MAX_VALUE ? currentIndex+ nextIndex = currentIndex< Integer.MAX_VALUE ? currentIndex+ 1 : 0 ; 
         } while (!atomicInteger.compareAndSet(currentIndex, nextIndex)); 
         return nextIndex % totalIndexes; 
     }  } 

totalIndex是索引的总数。 当请求下一个索引的请求时,计数器将增加,并进行比较和设置操作。 如果由于另一个线程而失败,则它将再次尝试该操作,并将获得计数器的下一个值。
模运算将给出当前索引。 如果原子整数达到最大值,则应将其重置为零。 重置会导致边缘情况并更改索引的顺序。 如果这是一个问题,则可以根据总索引大小来调整最大值以避免这种情况。

还对此进行了一些测试。

 package com.gkatzioura.concurrency;  import java.util.ArrayList;  import java.util.List;  import java.util.concurrent.ExecutionException;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.Future;  import org.junit.jupiter.api.Assertions;  import org.junit.jupiter.api.BeforeEach;  import org.junit.jupiter.api.Test;  AtomicIntegerRoundRobinTest { class AtomicIntegerRoundRobinTest { 
     private static final int MAX_INDEX = 10 ; 
     private AtomicIntegerRoundRobin atomicIntegerRoundRobin; 
     @BeforeEach 
     void setUp() { 
         atomicIntegerRoundRobin = new AtomicIntegerRoundRobin(MAX_INDEX); 
     } 
     @Test 
     void testIndexesSerially() { 
         for ( long i= 0 ;i<MAX_INDEX* 20 ;i++) { 
             System.out.println(atomicIntegerRoundRobin.index()); 
         } 
         Assertions.assertEquals( 0 , atomicIntegerRoundRobin.index()); 
     } 
     @Test 
     void testIndexesConcurrently() throws ExecutionException, InterruptedException { 
         ExecutorService executorService = Executors.newFixedThreadPool( 4 ); 
         List<Future> futures = new ArrayList(); 
         for ( int i = 0 ; i atomicIntegerRoundRobin.index())); 
         } 
         for (Future future: futures) { 
             System.out.println(future.get()); 
         } 
         Assertions.assertEquals( 0 ,atomicIntegerRoundRobin.index()); 
     }  } 

翻译自: https://www.javacodegeeks.com/2019/11/atomicinteger-on-java-and-round-robin.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值