欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Java和Round-Robin上的AtomicInteger

发布时间:2023/12/3 54 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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

创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

总结

以上是生活随笔为你收集整理的Java和Round-Robin上的AtomicInteger的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。