• 更快的原子类: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. [ 总结 ] vsftpd 虚拟用户配置

    需求:在不更改目录权限的前提下,ftp用户对目录里的文件拥有所有权. [root@server2 ~]# yum install vsftpd -y [root@server2 ~]# cd /etc ...

  2. MyBatis3-实现多表关联数据的查询

    前提: 1.新建Article表和增加模拟数据,脚本如下: Drop TABLE IF EXISTS `article`; Create TABLE `article` ( `id` ) NOT NU ...

  3. Scanner类的个人分析

    Scanner类读取键盘输入(java中Scanner类nextLine()和next()的区别和使用方法&&java 中的Scanner(非常详细不看后悔)): 2017/3/18 ...

  4. hdu 1348(凸包)

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. c#实现Form窗体始终在桌面最前端显示

    方法一 //调用API [System.Runtime.InteropServices.DllImport("user32", CharSet = System.Runtime.I ...

  6. 【xunsearch】笔记

    1.添加索引 $ cd /usr/local/xunsearch/sdk/php/ $ util/Indexer.php --rebuild --source=mysql://数据库用户名:数据库密码 ...

  7. Counting Haybales (线段树)

    Counting Haybales 时间限制: 50 Sec  内存限制: 256 MB提交: 52  解决: 18[提交][状态][讨论版] 题目描述 Farmer John is trying t ...

  8. mysql 获取当前日期及格式化(转)

    MySQL 获取当前日期及日期格式 获取系统日期: NOW() 格式化日期: DATE_FORMAT(date, format) 注: date:时间字段,format:日期格式 select now ...

  9. luogu P1772 [ZJOI2006]物流运输

    题目描述 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪. ...

  10. POJ 3180 The Cow Prom(SCC)

    [题目链接] http://poj.org/problem?id=3180 [题目大意] N头牛,M条有向绳子,能组成几个歌舞团?要求顺时针逆时针都能带动舞团内所有牛. [题解] 等价于求点数大于1的 ...