• 更快的原子类:LongAdder
     大家对AtomicInteger的基本实现机制应该比较了解,它们是在一个死循环内,不断尝试修改目标值,知道修改成功,如果竞争不激烈,那么修改成功的概率就很高,否则,修改失败的概率就很高,在大量修改失败时,这些原子操作就会进行多次循环尝试,因此性能就会受到影响
     那么竞争激烈的时候,我们应该如何进一步提高系统性能呢?一种基本方案就是可以使用热点分离,将竞争的数据进行分解.基于这个思路,打击应该可以想到一种对传统AtomicInteger等原子类的改进方法,虽然在CAS操作中没有锁,但是像减少锁粒度这种分离热点的思路依然可以使用,一种可行的方案就是仿造ConcurrengHashMap,将热点数据分离,比如,可以将AtomicInteger的内部核心数据value分离成一个数组,每个线程访问时,通过哈希等算法映射到其中一个数字进行计数,而最终的计数结果,则为这个数组的求和累加,其中,热点数据value被分离成多个单元cell,每个cell独自维护内部的值,当前对象的实际值由所有的cell累计合成,这样,热点就进行了有效的分离,提高了并行度,LongAdder正是使用了这种思想.
  • 测试LongAdder,原子类以及同步锁性能测试
public class LongAdderDemo {
private static final int MAX_THREADS = 3;
private static final int TASK_COUNT = 3;
private static final int TARGET_COUNT = 10000000; private AtomicLong acount = new AtomicLong(0L);
private LongAdder lacount = new LongAdder();
private long count = 0; private static CountDownLatch cdlsync = new CountDownLatch(TASK_COUNT);
private static CountDownLatch cdlatomic = new CountDownLatch(TASK_COUNT);
private static CountDownLatch cdladdr = new CountDownLatch(TASK_COUNT); protected synchronized long inc() {
return ++count;
} protected synchronized long getCount() {
return count;
} public class SyncThread implements Runnable {
protected String name;
protected long starttime;
LongAdderDemo out; public SyncThread(long starttime, LongAdderDemo out) {
this.starttime = starttime;
this.out = out;
} @Override
public void run() {
long v = out.getCount();
while (v < TARGET_COUNT) {
v = out.inc();
}
long endtime = System.currentTimeMillis();
System.out.println("SyncThread spend:" + (endtime - starttime) + "ms" + " v" + v);
cdlsync.countDown();
}
} public void testSync() throws InterruptedException {
ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
long starttime = System.currentTimeMillis();
SyncThread sync = new SyncThread(starttime, this);
for (int i = 0; i < TASK_COUNT; i++) {
exe.submit(sync);
}
cdlsync.await();
exe.shutdown();
} public class AtomicThread implements Runnable {
protected String name;
protected long starttime; public AtomicThread(long starttime) {
this.starttime = starttime;
} @Override
public void run() {
long v = acount.get();
while (v < TARGET_COUNT) {
v = acount.incrementAndGet();
}
long endtime = System.currentTimeMillis();
System.out.println("AtomicThread spend:" + (endtime - starttime) + "ms" + " v" + v);
cdlatomic.countDown();
}
} public void testAtomic() throws InterruptedException {
ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
long starttime = System.currentTimeMillis();
AtomicThread atomic = new AtomicThread(starttime);
for (int i = 0; i < TASK_COUNT; i++) {
exe.submit(atomic);
}
cdlatomic.await();
exe.shutdown();
} public class LongAdderThread implements Runnable {
protected String name;
protected long starttime; public LongAdderThread(long starttime) {
this.starttime = starttime;
} @Override
public void run() {
long v = lacount.sum();
while (v < TARGET_COUNT) {
lacount.increment();
v = lacount.sum();
}
long endtime = System.currentTimeMillis();
System.out.println("LongAdderThread spend:" + (endtime - starttime) + "ms" + " v" + v);
cdladdr.countDown();
} } public void testLongAdder() throws InterruptedException {
ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
long starttime = System.currentTimeMillis();
LongAdderThread atomic = new LongAdderThread(starttime);
for (int i = 0; i < TASK_COUNT; i++) {
exe.submit(atomic);
}
cdladdr.await();
exe.shutdown();
} public static void main(String[] args) throws InterruptedException {
LongAdderDemo demo = new LongAdderDemo();
demo.testSync();
demo.testAtomic();
demo.testLongAdder();
}
}
 
     

Java8 更快的原子类:LongAdder(笔记)的更多相关文章

  1. J.U.C体系进阶(三)- juc-atomic 原子类框架

    Java - J.U.C体系进阶 作者:Kerwin 邮箱:806857264@qq.com 说到做到,就是我的忍道! juc-atomic 原子类框架 AtomicInteger AtomicInt ...

  2. Android并发编程 原子类与并发容器

    在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的. 前言 上一篇博文中,主要说了些线程以及锁的东西,我们大多数的并发开发需求,基本上可以用synch ...

  3. JUC之原子类

    在分析原子类之前,先来了解CAS操作 CAS CAS,compare and swap的缩写,中文翻译成比较并交换. CAS 操作包含三个操作数 —— 内存位置(V).预期原值(A)和新值(B).如果 ...

  4. 死磕 java原子类之终结篇(面试题)

    概览 原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程上下文切换. 原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割 ...

  5. JUC源码学习笔记4——原子类,CAS,Volatile内存屏障,缓存伪共享与UnSafe相关方法

    JUC源码学习笔记4--原子类,CAS,Volatile内存屏障,缓存伪共享与UnSafe相关方法 volatile的原理和内存屏障参考<Java并发编程的艺术> 原子类源码基于JDK8 ...

  6. 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理

    (1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...

  7. JDK1.8源码阅读笔记(2) AtomicInteger AtomicLong AtomicBoolean原子类

    JDK1.8源码阅读笔记(2) AtomicInteger AtomicLong AtomicBoolean原子类 Unsafe Java中无法直接操作一块内存区域,不能像C++中那样可以自己申请内存 ...

  8. Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析

    默认的情况下,我们平时上网用的本地DNS服务器都是使用电信或者联通的,但是这样也导致了不少的问题,首当其冲的就是上网时经常莫名地弹出广告,或者莫名的流量被消耗掉导致网速变慢.其次是部分网站域名不能正常 ...

  9. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

随机推荐

  1. 【C++】各种成员变量

    来自:黄邦勇帅 const 常量对象: 即把对象声明为常量,即 const hyong m,常量对象不能调用可能改变对象的值的函数,因此常量对象只能调用类中的 const 常量函数,因为不是 cons ...

  2. kafka consumer 代码示例

    使用者小组 使得许多进程的多台机器 在逻辑上作为一个单个的使用者 出现. 我们使用中,一种常见的情况是,我们按照逻辑划分出多个使用者小组,每个小组都是有作为一个逻辑整体的多台使用者计算机组成的集群. ...

  3. Selenium2+python自动化31-生成测试报告【转载】

    前言 最近小伙伴们总有一些测试报告的问题,网上的一些资料生成报告的方法,我试了都不行,完全生成不了,不知道他们是怎么生成的,同样的代码,有待研究. 今天小编写一下可以生成测试报告的方法.个人觉得也是最 ...

  4. CWnd创建WS_CHILD和WS_POPUP窗口的不同

    转载:http://blog.csdn.net/tangaowen/article/details/6054152 最近在写一个从CWnd派生出来的自绘窗口,以前在包装自己的类的Create函数都是这 ...

  5. ThinkPHP的静态化页面方法

    原来ThinkPHP自带了生成静态页的函数buildHtml,使用起来很方便!最新的手册里没写这个方法,向大家介绍一下.     protected function buildHtml($htmlf ...

  6. Codeforces 626 C. Block Towers-二分 (8VC Venture Cup 2016-Elimination Round)

      C. Block Towers   time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. CF 990A. Commentary Boxes【数学/模拟】

    [链接]:CF [题意]:对于一个数n,每次加一的代价是a,每次减一的代价是b,求被m整除时的最小代价. [分析]:分情况讨论,自己多举几个栗子. [代码]: #include<cstdio&g ...

  8. WebApi 的三种寄宿方式 (二) - 宿主和控制器不在一个程序集

    新建一个类库: SelfHost: 方法一: 1.添加对MyControllers类库的引用. 2.在控制台代码中加入一行代码: 当然,可以添加多个程序集.(记得引用) var config = ne ...

  9. RobotFramework自动化测试框架系统关键字之断言

    一.基础 RobotFramework带有丰富的系统关键,使用时无需导入,直接使用,为写自动化用例带来了极大的方便:不能停留在知道或者是会得程度,只有熟练使用各关键字,才能提升自动化用例的写作效率.下 ...

  10. [LOJ#2540][PKUWC2018]随机算法(概率DP)

    场上数据很水,比较暴力的做法都可以过90分以上,下面说几个做法. 1. 暴力枚举所有最大独立集,对每个独立集分别DP.复杂度玄学,但是由于最大独立集并不多,所以可以拿90. 2. dp[S][k]表示 ...