场景引入

    经常都会有下面这段代码,多个线程同时修改一个变量,造成线程不安全,代码如下:

public class ThreadCASDemo implements Runnable {
static int counter=0;
static final Object objLock=new Object(); @Override
public void run() {
counter++;
System.out.println("counter"+counter);
} public static void main(String[] args) {
for (int i = 0; i <20 ; i++) {
ThreadCASDemo threadCASDemo=new ThreadCASDemo();
Thread th=new Thread(threadCASDemo);
th.start();
}
try {
Thread.sleep(2000);
}
catch (Exception ex){ }
System.out.println(counter);
}
}

  解决方案

    加synchronized锁

public class ThreadCASDemo implements Runnable {
static int counter=0;
static final Object objLock=new Object(); @Override
public void run() {
synchronized (objLock) {
counter++;
}
System.out.println("counter"+counter);
} public static void main(String[] args) {
for (int i = 0; i <20 ; i++) {
ThreadCASDemo threadCASDemo=new ThreadCASDemo();
Thread th=new Thread(threadCASDemo);
th.start();
}
try {
Thread.sleep(2000);
}
catch (Exception ex){ }
System.out.println(counter);
}
}

    加synchronized锁的原理示意图如下:

    

    一个个线程排队去更新这个值,这样就感觉太笨重了。synchronized是用来解决更复杂的并发编程场景的。

    而且在这个场景下,你一个个排队,加锁处理数据,释放锁,下一个再进来不就相当于串行化了吗。

    Atomic原子类

public class ThreadCASAtomic implements Runnable {
static AtomicInteger ati=new AtomicInteger(0);
static final Object objLock=new Object(); @Override
public void run() {
Integer counter=ati.incrementAndGet();
System.out.println("counter"+counter);
} public static void main(String[] args) {
for (int i = 0; i <20 ; i++) {
ThreadCASDemo threadCASDemo=new ThreadCASDemo();
Thread th=new Thread(threadCASDemo);
th.start();
}
}
}

    这个之所以效率更高,因为底层是无锁化的CAS。(Compare And Set)。

    底层原理如下:每个线程都会先获取当前的值,接着走一个CAS操作,原子的意思就是这个CAS操作一定是自己完整执行完的,不会被别人打断的。

    然后CAS操作里,会比较一下说:大兄弟,现在你的值不是我刚刚才获取到的那个值啊?

    如果是的化,说明没人改过这个值,那你就给我设置累加1的操作,如果不是的话,发现自己获取的值跟当前的值不一样,会导致CAS失败,失败之后,进入一个无线循环,再次获取值,进行CAS操作。

  Java 8 中对CAS机制的优化

    上面的做法问题就出现在,如果大量的线程同时并发修改一个AtomicInteger,可能会有很多线程,不停的自旋,进入一个无线的重复循环中。

    这些线程不停的获取值,不停的失败。

    在高并发的时候,这种情况就会很明显,导致性能和效率都不高。

    所以java 8 提出了一个LongAdder,他就是尝试使用分段CAS以及自动分段迁移的方式来大幅度提高多线程高并发执行CAS的操作性能。  

    

  

            

java8 如何优化CAS的性能的更多相关文章

  1. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互

    java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...

  2. 如何快速优化手游性能问题?从UGUI优化说起

    WeTest 导读   本文作者从自身多年的Unity项目UI开发及优化的经验出发,从UGUI,CPU,GPU以及unity特有资源等几个维度,介绍了unity手游性能优化的一些方法.   在之前的文 ...

  3. SQL常见优化Sql查询性能的方法有哪些?

    常见优化Sql查询性能的方法有哪些? 1.查询条件减少使用函数,避免全表扫描 2.减少不必要的表连接 3.有些数据操作的业务逻辑可以放到应用层进行实现 4.可以使用with as 5.使用“临时表”暂 ...

  4. CSS性能分析,如何优化CSS提高性能

    不负十年后的自己,共勉! 前端性能优化一直是一个比较热门的话题,我们总是在尽我们最大的努力去,提高我们的页面性能,比如减少HTTP请求,利用工具对资源进行合并压缩,脚本置底,避免重复请求,css sp ...

  5. 通过 SMB 直通优化文件服务器的性能

    https://technet.microsoft.com/zh-cn/library/hh831487.aspx Windows Server 2012 内置新增功能,称为 SMB 直通,用来支持使 ...

  6. Tomcat 7优化前及优化后的性能对比

    Tomcat 7在我们日常开发.测试.生产环境都会使用到,但对于大部分开发人员来说,对其性能还是没有多大了解.本文就对它做一次性能测试,对比优化前后的性能区别. 一.运行环境 CPU: Intel(R ...

  7. 【转】利用TCMalloc优化Nginx的性能

    From: http://www.linuxidc.com/Linux/2013-04/83197.html TCMalloc的全称是 Thread-Caching Malloc,是谷歌开发的开源工具 ...

  8. Android App性能优化笔记之一:性能优化是什么及为什么?

    By Long Luo   周星驰的电影<功夫>里面借火云邪神之口说出了一句至理名言:“天下武功,唯快不破”. 在移动互联网时代,同样如此,留给一个公司的窗口往往只有很短的时间,如何把握住 ...

  9. [Unity优化] Unity CPU性能优化

    前段时间本人转战unity手游,由于作者(Chwen)之前参与端游开发,有些端游的经验可以直接移植到手游,比如项目框架架构.代码设计.部分性能分析,而对于移动终端而言,CPU.内存.显卡甚至电池等硬件 ...

随机推荐

  1. gin框架中请求路由组的使用

    1. gin框架中可以使用路由组来实现对路由的分类 package main import "github.com/gin-gonic/gin" func main() { rou ...

  2. golang中的标准库strconv

    strconv 包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi().Itia().parse系列.format系列.append系列. string与int ...

  3. 通俗易懂详解iptables

    防火墙相关概念 从逻辑上讲.防火墙可以大体分为主机防火墙和网络防火墙. 主机防火墙:针对于单个主机进行防护. 网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网. ...

  4. Ldap主从复制搭建

    LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写, LDAP协议的特点 读取速度远高于写入速度. 对查询做了优化,读取速度优于普通关系数据 ...

  5. python函数位置实参传参

    #!/usr/bin/python #coding=utf-8 #好好学习,天天向上 def describe_pet(type,name): print(f"i have a {type} ...

  6. numpy 矩阵在作为函数参数传递时的奇怪点

    numpy 矩阵在作为函数参数传递时的奇怪点 import numpy as np class simpleNet: def __init__(self): self.W = np.array([1, ...

  7. AI算法测评(二)--算法测试流程

    根据算法测试过程中遇到的一些问题和管理规范, 梳理出算法测试工作需要关注的一些点: 编号 名称 描述信息 备注 1 明确算法测试需求 明确测试目的 明确测试需求, 确认测试需要的数据及场景 明确算法服 ...

  8. CF Round #530 Div2

    A. 尛你 \(\%\%\%\) B. 题意:你需要在平面上画 \(n(n \le 10 ^ 9)\) 个 \(1 \times 1\) 的正方形,且顶点都在整点上,每次可以画一条长度为 \(1\) ...

  9. new Date时间格式转换方法

    平时经常会使用到时间转换,组件库已经有很多组件可以自动生成时间类型了,但是底层的封装方法还是得有 获取当前时间 new Date()  或者自己拥有一个毫秒时间 方法如下 /** * title: 时 ...

  10. bom案例1-div拖拽

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...