• 为什么CAS加锁是线程安全的?--理解原子操作


    引入

    • 在Java中实现并发用的最多的就是synchronized关键字了,自从jdk1.6对synchronized进行重大优化后,其广为人诟病的性能问题也得到了改善,与ReentrankLock相比性能方面相差无几

    • 性能的改善得益于偏向锁、轻量级锁的引入,它们具体的实现方式可参考《Java并发编程的艺术》和《深入理解Java虚拟机》这两本书。偏向锁、轻量级锁和重量级锁不同的地方在于不是通过信号量机制(强制阻塞)而是通过自旋CAS实现互斥访问的,避免了强制阻塞时用户态与核心态之间切换带来的开销(系统调用),这里的开销主要是保存用户态的上下文信息。

    自旋CAS

    • CAS操作是一个原子操作,所谓原子操作就是指在执行期间不会被其他线程打断,要么执行完毕,要么不执行

    • CAS操作有三个操作数V(内存地址),A(旧的预期值),B(准备设置的新值)。指令执行时先看V指向的内存中存储的值是否和A相同,如果相同才会更新为B,否则什么也不做。

    • 自旋是指当对象或同步块已经被其他线程锁定时,竞争线程空转等待占用线程执行完毕的情形。注意此时竞争线程并没有阻塞,而是原地空转,执行一个无限循环判断对象是否已解锁,所以不存在用户态到核心态的转换,因而同步效率较高(但会占用CPU时间)。

    从问题出发理解原子性

    • 我一直有个疑惑,CAS的原子性和使用CAS加锁保证线程安全有什么关系?假设有多个线程同时在对同一块内存进行CAS操作的话,那不就有可能出问题吗:两个线程T1,T2同时对同一对象执行CAS操作加锁,V存储同一块内存地址,A当然也是同样旧的预期值,那么这种情况下T1和T2都可以进行更新,那么CAS操作加锁过程就是无效的,因为CAS操作成功后线程就会进入同步块,此时就会有多个线程同时执行同步块中的代码······那这不就会使同步块线程不安全了吗。

    • 后来我明白了CAS原子性和线程安全的关系,在多个线程同时CAS的情况下是不会发生多个线程CAS成功的情况的,因为计算机底层实现保证了V指向内存的互斥性和立即可见性,可以理解为CAS操作是底层保证的线程安全

    • 首先说结论,一个线程T在CAS操作时,其他线程无法访问V指向的内存地址,并且一旦T更新了V指向内存中的值,其他所有线程的V指向内存都变得无效。

    • 处理器实现原子操作有两种做法

      • 一是总线锁,在多CPU 下,当其中一个处理器要对共享内存进行操作的时候,在总线上发出一个 LOCK# 信号,这个信号使得其他处理器无法通过总线来访问到共享内存中的数据

      • 二是缓存锁,如果共享内存已经被缓存,那么锁总线没有意义。缓存锁核心是使用了缓存一致性协议,如MESI协议

        • MSEI表示缓存行的四种状态

          • M(Modify) 表示共享数据只缓存在当前 CPU 缓存中, 并且是被修改状态,也就是缓存的数据和主内存中的数据不一致

          • E(Exclusive) 表示缓存的独占状态,数据只缓存在当前 CPU 缓存中,并且没有被修改

          • S(Shared) 表示数据可能被多个 CPU 缓存,并且各个缓存中的数据和主内存数据一致

          • I(Invalid) 表示缓存已经失效

        • MESI 协议中,每个缓存的缓存控制器不仅知道自己的 读写操作,而且也监听(snoop)其它 Cache 的读写操作

        • CPU在读数据时,如果缓存行状态是I,则需要从内存中读取,并把缓存行状态置为S;如果不是I,则可以直接读取缓存中的值,但在此之前必须要等待对其他CPU的监听结果,如果其他CPU也有该数据的缓存且状态是M,则需要等待其把缓存更新到内存后再读取

        • CPU可以将状态为M/E/S的缓存写入内存,其中如果缓存行状态为S,则其他CPU缓存了相同数据的缓存行会无效化

    • 也就是说不会有多个线程同时访问共享变量,而且共享变量更新是对所有线程可见的,所以原子操作是线程安全的。

  • 相关阅读:
    POJ 1269 Intersecting Lines(判断两条线段关系)
    POJ 3304 Segments(判断直线和线段相交)
    poj 1383 Labyrinth【迷宫bfs+树的直径】
    poj 2631 Roads in the North【树的直径裸题】
    poj 1985 Cow Marathon【树的直径裸题】
    hdoj 1596 find the safest road【最短路变形,求最大安全系数】
    hdoj 1260 Tickets【dp】
    poj 1564 Sum It Up【dfs+去重】
    2014 牡丹江现场赛 i题 (zoj 3827 Information Entropy)
    hdoj 2473 Junk-Mail Filter【并查集节点的删除】
  • 原文地址:https://www.cnblogs.com/codespoon/p/13462765.html
Copyright © 2020-2023  润新知