paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
2
CAS(CompareAnd Swap/Set)操作automic数据类型AtomicLong,AtomicReference(Java提供的CAS操作)
4
内存屏障(MemoryBarries)和(javavolatile)代替传统lock.
作者Attilax 艾龙, EMAIL:1466519819@qq.com
来源:attilax的专栏
地址:http://blog.csdn.net/attilax
1 锁的缺点
2 CAS(Compare And Swap/Set)操作automic 数据类型AtomicLong,
AtomicReference(Java提供的CAS操作)
这是一个CPU级别的指令,在我的意识中,它的工作方式有点像乐观锁——CPU去更新一个值,但如果想改的值不再是原来的值,操作就失败,因为很明显,有其它操作先改变了这个值。
改变了这个值。
注意,这可以是CPU的两个不同的核心,但不会是两个独立的CPU。
CAS操作比锁消耗资源少的多,因为它们不牵涉操作系统,它们直接在CPU上操作。但它们并非没有代价——在上面的试验中,单线程无锁耗时 300ms,单线程有锁耗时10000ms,单线程使用CAS耗时5700ms。所以它比使用锁耗时少,但比不需要考虑竞争的单线程耗时多。
3 Threadlocal
没有竞争=没有锁=非常快。
Disruptor相对于传统方式的优点:
- 没有竞争=没有锁=非常快。
- 所有访问者都记录自己的序号的实现方式,允许多个生产者与多个消费者共享相同的数据结构。
- 在每个对象中都能跟踪序列号(ring buffer,claim Strategy,生产者和消费者),加上神奇的cache line padding,就意味着没有为伪共享和非预期的竞争。
4 内存屏障(Memory Barries)和(java volatile)代替传统lock
Volatile是轻量级的synchronized... Volatile变量修饰符如果使用恰当的话,它比synchronized的使用和执行成本会更低,因为它不会引起线程上下文的切换和调度。
从volatile关键字开始的吧,知道它可以保证变量的可见性,而且利用它可以实现读与写的原子操作。。。但是要实现一些复合的操作volatile就无能为力了。。。最典型的代表是递增和递减的操作。。。
它是一个CPU指令。没错,又一次,我们在讨论CPU级别的东西,以便获得我们想要的性能(Martin著名的 Mechanical Sympathy理论)。基本上,它是这样一条指令: a)确保一些特定操作执行的顺序; b)影响一些数据的可见性(可能是某些指令执行后的结果)。
编译器和CPU可以在保证输出结果一样的情况下对指令重排序,使性能得到优化。插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。正如去拉斯维加斯旅途中各个站点的先后顺序在你心中都一清二楚。
存屏障另一个作用是强制更新一次不同CPU的缓存。例如,一个写屏障会把这个屏障前写入的数据刷新到缓存,这样任何试图读取该数据的线程将得到最新值,而不用考虑到底是被哪个cpu核心或者哪颗CPU执行的。
这里有个神奇咒语叫volatile(我觉得这个词在Java规范中从未被解释清楚)。如果你的字段是volatile,Java内存模型将在写操作后插入一个写屏障指令,在读操作前插入一个读屏障指令。
这意味着如果你对一个volatile字段进行写操作,你必须知道:
1、一旦你完成写入,任何访问这个字段的线程将会得到最新的值。
2、在你写入前,会保证所有之前发生的事已经发生,并且任何更新过的数据值也是可见的,因为内存屏障会把之前的写入值都刷新到缓存。
volatile变量,同时也是我们能够不用锁操作就能实现Disruptor的原因之一。
对性能的影响
内存屏障作为另一个CPU级的指令,没有锁那样大的开销。内核并没有在多个线程间干涉和调度。但凡事都是有代价的。内存屏障的确是有开销的——编译器/cpu不能重排序指令,导致不可以尽可能地高效利用CPU,另外刷新缓存亦会有开销。所以不要以为用volatile代替锁操作就一点事都没。
内存屏障是CPU指令,它允许你对数据什么时候对其他进程可见作出假设。在Java里,你使用volatile关键字来实现内存屏障。使用volatile意味着你不用被迫选择加锁,并且还能让你获得性能的提升。
5 . Disruptor(无锁并发框架)
6
Peterson 算法
(Dekker算法的演化),这个算法设计得很巧妙,理解的核心就是搞清楚三个标志位是怎样控制两个方法对临界区的访问的:
7 、函数式编码。
函数式编码是最天然的和最高效的免锁方式,
8 、资源局部复制、异步处理。
总所周知对资源的争夺是造成锁的一个重要原因,在很多情况下,资源只能有一份,但是对使用资源的每个线程来说,都可以看到属于它自己的一份(这一份并非是真正的资源,很可能只是一个缓冲区,每个线程使用它自己的一个缓冲区,到一定程度时将缓冲区的数据处理到唯一资源中,这就减少了需要加锁对线程的影响),无需考虑并发地去使用。
9 、Immutable object不变对象
以往很多的锁无关数据结构都以Immutable object 的方式去达致线程安全,这很像Java 中的 String ,但因为涉及过多的复制操作,令性能低下。
10 参考
Java的无锁编程和锁优化 - kjfcpua的专栏 - 博客频道 -CSDN.NET.htm
Java的无锁编程和锁优化 - kjfcpua的专栏 - 博客频道 -CSDN.NET.htm
聊聊并发(一)深入分析Volatile的实现原理 _ 并发编程网 - ifeve.com.htm
剖析Disruptor 为什么会这么快?(一)锁的缺点 _ 并发编程网 -ifeve.com.htm
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)的更多相关文章
- 基于CAS实现无锁结构
杨乾成 2017310500302 一.题目要求 基于CAS(Compare and Swap)实现一个无锁结构,可考虑queue,stack,hashmap,freelist等. 能够支持多个线程同 ...
- paip.提升性能--多核cpu中的java/.net/php/c++编程
paip.提升性能--多核cpu中的java/.net/php/c++编程 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...
- paip.提升性能---jvm java 工具使用.
paip.提升性能---jvm java 工具使用. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...
- paip.提升性能--多核编程中的java .net php c++最佳实践 v2.0 cah
paip.提升性能--多核编程中的java .net php c++最佳实践 v2.0 cah 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax ...
- paip.提升性能---并行多核编程哈的数据结构list,set,map
paip.提升性能---并行多核编程哈的数据结构list,set,map vector/copyonwritearraylist 都是线程安全的. 或者经过包装的list ::: collection ...
- 无锁算法CAS 概述
无锁算法CAS 概述 JDK5.0以后的版本都引入了高级并发特性,大多数的特性在java.util.concurrent包中,是专门用于多线并发编程的,充分利用了现代多处理器和多核心系统的功能以编写大 ...
- paip. 提升性能---hibernate的缓存使用 总结
paip. 提升性能---hibernate的缓存使用 总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...
- paip.提升性能----jvm参数调整.txt
paip.提升性能----jvm参数调整.txt 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.n ...
- paip.提升性能---协程“微线程”的使用.
paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...
随机推荐
- java.net.MalformedURLException: Illegal character in URL
在进行接口测试时,意外发现返回结果报java.net.MalformedURLException: Illegal character in URL,意思是“在URL中的非法字符”,我的参数是经过ba ...
- 如何使用JS脚本从HTML中分离图片标签与文本,替换文本中指定的内容并加粗(原创)
var html='ddfsdfsdfdsd dfsdfsdffds<img _src="http://localhost:8490/60E86EA7-FE7B-44BF-8270-4 ...
- Linux ps命令详解与示例说明
ps:要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本同时也是非常强大的进程查看命令.使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结 ...
- opencv写视频
代码: #include<opencv2/opencv.hpp> using namespace cv; #include<string> using namespace st ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 背景: mys ...
- Maven学习之 Settings
虽然天天在用,但是没有系统的学习过,总觉得别扭. 只能用于Java项目. 约定: repository 翻译成 仓库 build 翻译成 构建 build system 翻译成 构建系统 build ...
- VB6.0 读取CSV文件
最近做了一个Upload文件的需求,文件的格式为CSV,读取文件的方法整理了一下,如下: 1.先写了一个读取CSV文件的Function: '读取CSV文件 '假设传入的参数strFile=C:\Do ...
- 0909 45作业one
1.编译原理学什么? 答: 初遇编译原理,我知道编译原理是计算机专业设置的一门重要的专业课程,主要是介绍编译程序构造的一般原理和基本方法.其内容大概包括语言和文法.词法分析.语法分析.语法制导翻译.中 ...
- 让linux中的程序崩溃时生成core文件
当我们的linux程序崩溃的时候,常常会有这样的提示: Segmentation fault (core dumped) 段错误 (核心已转储) 提示说生成了core文件,但是此功能 ...
- Javascript 添加自定义静态方法属性JS清除左右空格
例如加trim()清除左右空格 String.prototype.trim=function() { return this.replace(/(^\s*)|(\s*$)/g,''); } 调用 va ...