zoukankan      html  css  js  c++  java
  • Atomic原子类

    原子类实现原理:CAS(compare and swap)

    • CAS的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址。另外 value 是一个volatile变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。
    • CAS包含3个参数CAS(V,E,N).V表示要更新的变量, E表示预期值, N表示新值.仅当V值等于E值时, 才会将V的值设为N, 如果V值和E值不同, 则说明已经有其他线程做了更新, 则当前线程什么都不做. 最后, CAS返回当前V的真实值. CAS操作是抱着乐观的态度进行的, 它总是认为自己可以成功完成操作.当多个线程同时使用CAS操作一个变量时, 只有一个会胜出, 并成功更新, 其余均会失败.失败的线程不会被挂起,仅是被告知失败, 并且允许再次尝试, 当然也允许失败的线程放弃操作.基于这样的原理, CAS操作即使没有锁,也可以发现其他线程对当前线程的干扰, 并进行恰当的处理.

    原子类的ABA问题

    • 所谓ABA就是一个线程在CAS更新变量的时候,该变量已经被别的线程先从A该成了B,再从B该回了A,此时线程还是会CAS成功,因为它认为期望值并没有变
    • 解决办法是增加版本号,每次修改版本号加1
    • 实现版本号功能的类为AtomicStampedReference

    Atomic基本数据类型

    • AtomicInteger
    • AtomicLong
    • AtomicBoolean

    Atomic基本类型原子类常用方法

    • int get() // 获取当前值
    • int getAndSet(int value) // 获取当前值并设置成指定值等价于普通变量的i = value
    • int getAndIncrement() // 自增 ,等价于普通变量的i++
    • int getAndDecrement() // 自减,等价于普通变量的i--
    • int getAndAdd(int Value) // 加上预期值,等价于普通变量的i = i + value
    • boolean compareAndSet(int expect, int update) //如果该对象等于期望值,把它更新成update的值,等价于普通变量的`if (i == expect) {i = update}

    AtomicLong 和LongAdder(jdk8新增)

    LongAdder的原理:
    比如我需要将100 加个10 再加20,那么有下面这两种操作步骤:
    第一种:先将100+10 = 110,然后再110+20 得到最终结果 130。
    第二种:将100拆成2个50,在第一个50上面加10得到60,在最后一个50上加20得到70,最后将第一操作结果 60 和 第二次的操作结果70相加,得到最终的130。
    LongAdder就是第二种操作思路,将原AtomicLong里的value拆成多个value,这样在并发情况下,就将多个线程竞争修改【一个】value属性的机会 --> 多个线程竞争修改【多个】value属性的机会,这样就相当于将性能翻倍。
    在竞争激烈的情况下LongAdder的性能比AtomicLong的高很多

    数组类型AtomicLongArray

    用法和基本基本数据类型相似,但是函数参数会多一个索引i值,如自增getAndIncrement(int i),对数组的对应索引值做更新

  • 相关阅读:
    BZOJ2435 NOI2011道路修建
    BZOJ2431 HAOI2009逆序对数列(动态规划)
    BZOJ2456 mode
    BZOJ2324 ZJOI2011营救皮卡丘(floyd+上下界费用流)
    BZOJ2303 APIO2011方格染色(并查集)
    BZOJ2299 HAOI2011向量(数论)
    BZOJ2169 连边(动态规划)
    BZOJ2159 Crash的文明世界(树形dp+斯特林数)
    洛谷 P1306 斐波那契公约数 解题报告
    洛谷 P2389 电脑班的裁员 解题报告
  • 原文地址:https://www.cnblogs.com/zhz-8919/p/10803564.html
Copyright © 2011-2022 走看看