`
sunqi
  • 浏览: 227940 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

更快的AtomicInteger

    博客分类:
  • java
 
阅读更多

之前看了java8longadder实现,最近又看到一篇文章介绍longadder的,http://ifeve.com/atomiclong-and-longadder/

其实现思路也是分段,最后需要get的时候进行sum计算。其核心思路就是减少并发,但之前老的Atomic,难道就没有提升的空间了吗?昨晚进行了一次测试

 

  /**

     * Atomically increments by one the current value.

     *

     * @return the updated value

     */

    publicfinalint incrementAndGet() {

        for (;;) {

            int current = get();

            int next = current + 1;

            if (compareAndSet(current, next))

                return next;

        }

    }

incrementAndGet为例,在非常高的并发下,compareAndSet会很大概率失败,因此导致了此处cpu不断的自旋,对cpu资源的浪费

既然知道此地是高并发的瓶颈,有什么办法呢?

 

publicclass AtomicBetter {

       AtomicInteger ai = new AtomicInteger();

      

       publicint incrementAndGet() {

              for (;;) {

                     int current = ai.get();

                     int next = current + 1;

                     if (compareAndSet(current, next))

                            return next;

              }

       }

       /**

       * 如果cas失败,线程park

       * @param current

       * @param next

       * @return

       */

       privateboolean compareAndSet(int current, int next) {

              if (ai.compareAndSet(current, next)) {

                     returntrue;

              } else {

                     LockSupport.parkNanos(1);

                     returnfalse;

              }

       }

 

}

很简单,当cas失败后,对线程park,减少多线程竞争导致的频繁cas失败,更进一步的导致cpu自旋,浪费cpu的运算能力

 

4核虚拟机,Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz  linux 2.6.32,注意,老版本的内核,不支持高ns级的精度

下进行测试,同样都起4个线程,每个线程里面对AtomicInteger进行5kw次的incrementAndGet

 

原生的AtomicInteger,耗时14232ms,进行了35870次上下文切换,总共87967770955次时钟周期

prak 1ns下呢,耗时5195ms,进行了19779次上下文切换,总共36187480878次时钟周期

 

明显性能上比原生的AtomicInteger更好,那这个park多少合适呢?那就只有人肉测试了

 

park

time ms

context-switches

cycles

AtomicInteger

14232

35,870

87,967,770,955

1ns

5195

19,779

36,187,480,878

10ns

5050

20,223

34,839,351,263

100ns

5238

20,724

37,250,431,417

125ns

4536

47,479

26,149,046,788

140ns

4008

100,022

18,342,728,517

150ns

3864

110,720

16,146,816,453

200ns

3561

125,694

11,793,941,243

300ns

3456

127,072

10,200,338,988

500ns

3410

132,163

9,545,542,340

1us

3376

134,463

9,125,973,290

5us

3383

122,795

9,009,226,315

10us

3367

113,930

8,905,263,507

100us

3391

50,925

8,359,532,733

500us

3456

17,225

8,096,303,146

1ms

3486

10,982

7,993,812,198

10ms

3456

2,600

7,845,610,195

100ms

3555

1,020

7,804,575,756

500ms

3854

822

7,814,209,077

 

 

 

 

 

 

 

 

 

 

 

 

本机环境下,park 1ms下,相对耗时,cs次数来说是最好的。因此这种优化要达到最佳效果,还要看cpu的情况而定,不是一概而定的

两个问题:

<!--[if !supportLists]-->1、<!--[endif]-->cas失败对线程park的副作用是什么

<!--[if !supportLists]-->2、<!--[endif]-->如果park的时间继续加大,那会是这么样的结果呢

 

 

  • 大小: 22.3 KB
  • 大小: 25.1 KB
  • 大小: 25.2 KB
分享到:
评论

相关推荐

    AtomicInteger并发测试

    测试java.util.concurrent.atomic.AtomicInteger的类 与直接使用int做区别

    AtomicInteger 浅谈

    NULL 博文链接:https://zcmor.iteye.com/blog/1535524

    Java中对AtomicInteger和int值在多线程下递增操作的测试

    主要介绍了Java中对AtomicInteger和int值在多线程下递增操作的测试,本文得出AtomicInteger操作 与 int操作的效率大致相差在50-80倍上下的结论,需要的朋友可以参考下

    Java AtomicInteger类的使用方法详解

    主要介绍了Java AtomicInteger类的使用方法详解,文中有具体实例代码,具有一定参考价值,需要的朋友可以了解下。

    AtomicInteger的使用,CAS的工作原理

    AtomicInteger atomicInteger = new AtomicInteger(5); atomicInteger.compareAndSet(5, 2020) + \t current data is + atomicInteger.get()) /** * Atomically sets the value to the given updated value * if ...

    java并发之AtomicInteger源码分析

    AtomicInteger是java并发包下面提供的原子类,主要操作的是int类型的整型,通过调用底层Unsafe的CAS等方法实现原子操作。下面小编和大家一起学习一下

    Java AtomicInteger类使用方法实例讲解

    主要介绍了Java AtomicInteger类使用方法实例讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    ViewPager+AtomicInteger实现广告轮播

    利用ViewPager实现的广告轮播,没有触摸事件的时候可以定时轮播广告,有触摸事件实施触摸事件。自动轮播使用的是线程加AtomicInteger的方式实现。

    AtomicIntegerExample:AtomicInteger示例

    AtomicInteger示例AtomicInteger用于原子增量计数器之类的应用程序。 简短的示例代码: public class AtomicIntegerExample { private final ExecutorService execService = Executors . newFixedThreadPool( 100 );...

    JAVA初级面试题(release)

    NULL 博文链接:https://it-fan.iteye.com/blog/1183175

    线程基础,线程池,生命周期

    线程基础,线程池,生命周期

    Redis数据结构与对象总结

    Redis数据结构与对象总结 数据结构与对象 简单动态字符串 SDS简介 SDS与C字符串的区别 常数复杂度获取字符串长度 O(n) O(1) 杜绝缓冲区溢出 修改字符串长度时内存重分配 空间预分配:对字符串进行增长操作时...

    java多线程自增效率比较及原理解析

    在多线程环境下,对于自增操作需要考虑线程安全问题,常见的解决方法包括使用synchronized关键字、AtomicInteger、LongAdder和LongAccumulator等。本文给出了使用这些方法实现自增的代码演示,并通过多线程测试比较...

    java 分页、批量删除

    包含了jsp的简单分页,有首页、尾页、上下页、设置页面数字等,有完整的注释、包、ppt等,mysql数据库的,对后台管理的删除有不错的参考价值,非常适合web初学者,改改就可以在多少场合运用。

    用Java代码所写的简单计数器

    用Java代码所写的简单计数器,功能:根据选票人投票,最后记录数据并用立方图显示结果

    使用Java的Memory Model实现一个简单的计数器.txt

    这个代码实现了一个简单的计数器,使用了Java的`AtomicInteger`类来保证多线程环境下的原子性操作。`AtomicInteger`是一个支持原子操作的整数类,它内部使用了CAS(Compare And Swap)算法来实现线程安全的操作。在...

    fastjson-1.2.30.zip

    增加对 android 版本序列化的 AtomicInteger/AtomicLong 支持 修改下划线或者相似属性重复时解析结果不对的问题 #1089 反序列化增强对非静态内嵌类的支持,提供更友好的出错信息 #1082 新增反序列化特性 Feature....

    JUC多线程学习个人笔记

    原子操作:JUC提供了一些原子操作类,如AtomicInteger、AtomicLong等,可以实现线程安全的原子操作,避免了使用synchronized关键字的性能损耗。 锁机制:JUC提供了Lock接口和Condition接口,可以实现更细粒度的锁...

    Java并发编程相关源码集 包括多任务线程,线程池等.rar

     volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...

    kotlinx.atomicfu:在Kotlin中使用原子操作的惯用方式

    kotlinx.atomicfu:在Kotlin中使用原子操作的惯用方式

Global site tag (gtag.js) - Google Analytics