paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

1    
锁的缺点

2    
CAS(CompareAnd Swap/Set)操作automic数据类型AtomicLong,AtomicReference(Java提供的CAS操作)

3    
Threadlocal

4    
内存屏障(MemoryBarries)和(javavolatile)代替传统lock.

5    
. Disruptor(无锁并发框架)

6    
Peterson算法

7    
、函数式编码。

8    
、资源局部复制、异步处理。

9    
、Immutableobject不变对象

10      
参考

作者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相对于传统方式的优点:

  1. 没有竞争=没有锁=非常快。
  2. 所有访问者都记录自己的序号的实现方式,允许多个生产者与多个消费者共享相同的数据结构。
  3. 在每个对象中都能跟踪序列号(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, 函数式编码, 不变对象)的更多相关文章

  1. 基于CAS实现无锁结构

    杨乾成 2017310500302 一.题目要求 基于CAS(Compare and Swap)实现一个无锁结构,可考虑queue,stack,hashmap,freelist等. 能够支持多个线程同 ...

  2. paip.提升性能--多核cpu中的java/.net/php/c++编程

    paip.提升性能--多核cpu中的java/.net/php/c++编程 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http ...

  3. paip.提升性能---jvm java 工具使用.

    paip.提升性能---jvm java 工具使用. 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...

  4. paip.提升性能--多核编程中的java .net php c++最佳实践 v2.0 cah

    paip.提升性能--多核编程中的java .net php c++最佳实践  v2.0 cah 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax ...

  5. paip.提升性能---并行多核编程哈的数据结构list,set,map

    paip.提升性能---并行多核编程哈的数据结构list,set,map vector/copyonwritearraylist 都是线程安全的. 或者经过包装的list ::: collection ...

  6. 无锁算法CAS 概述

    无锁算法CAS 概述 JDK5.0以后的版本都引入了高级并发特性,大多数的特性在java.util.concurrent包中,是专门用于多线并发编程的,充分利用了现代多处理器和多核心系统的功能以编写大 ...

  7. paip. 提升性能---hibernate的缓存使用 总结

    paip. 提升性能---hibernate的缓存使用 总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog ...

  8. paip.提升性能----jvm参数调整.txt

    paip.提升性能----jvm参数调整.txt 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.n ...

  9. paip.提升性能---协程“微线程”的使用.

    paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...

随机推荐

  1. EF联合查询的新用法

    用EF很多年了,做联合查询时,只知道linq和lambda两种语法,今天朋友发了一个链接,打开看后发现是EF内置的新的关于联合查询的方法,赶紧抄录下来,以备后用. 现在先把这几种方法,各写一个例子,便 ...

  2. linux 下部署 redis

    Redis是一种高级key-value数据库.它跟memcached类似,不过数据 可以持久化,而且支持的数据类型很丰富.有字符串,链表,集 合和有序集合.支持在服务器端计算集合的并,交和补集(dif ...

  3. 【转】HTTP状态码(HTTP Status Code)

    原文链接:http://www.chaoji.com/features/httpstatus.aspx 一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - ...

  4. C#签名 NX90

    1.在VS中添加D:\Siemens\NX90\ \NXSigningResource.res文件,右击文件属性,将资源变为 嵌入式资源,即生成方式 2.编译生成exe文件或者dll文件,例如:xxx ...

  5. 深入浅出Symfony2 - 如何提高网站响应速度 [转]

    简介 Symfony2是一个基于PHP语言的Web开发框架,有着开发速度快.性能高等特点.但Symfony2的学习曲线也比较陡峭,没有经验的初学者往往需要一些练习才能掌握其特性.相对其他框架,Symf ...

  6. secure erase 时必须umount

    不umont就进行secure erase,仍然会执行成功,但是ssd确没有被清0,使用hexdump可以验证. 但是secure erase 命令却返回成功,造成误解以为已经擦除成功. 所以,sec ...

  7. 【Java】XML解析之SAX

    SAX介绍 SAX(Simple API for XML)是一种事件驱动的流式XML文件处理方式,区别与DOM方式的是不需要在内存中建一棵DOM树,而是根据读取XML时遇到的标签事件来顺序处理,因此具 ...

  8. sqlite数据库中 保存和读取UIData对象

    + (void)getPersonByID:(int)ID { sqlite3 *db = [DB open]; sqlite3_stmt *stmt = nil; int result = sqli ...

  9. 关于把A表中的数据复制到B表中(整理)

    如果A,B两个表中没有重复数据且表结构一样可以直接 insert into B select * from A 如果结构不一样可以 insert into B(字段列表),select 字段列表 fr ...

  10. Mispelling 1510

    #include<iostream>#include<string>#include<cstdio>using namespace std;int main(){  ...