您的位置:首页 > 编程语言 > Java开发

java并发编程实战-原子变量与非阻塞同步机制

2017-07-24 22:30 169 查看
1,近年来,在并发算法领域的大多数研究都侧重于非阻塞算法,这种算法用底层的原子机器指令(例如比较并交换指令)代替锁来确保数据在并发访问中的一致性。
2,与基于锁的方案相比,非阻塞算法在设计和实现上都要复杂得多,但它们在可伸缩性和活跃性上却拥有巨大的优势。

3,锁的劣势


  3.1,当有多个线程同时请求锁时,JVM需要借助操作系统的功能,将线程挂起并且在稍后恢复运行。当锁上存在着激烈的竞争时,调度开销与工作开销的比值会比较高

  3.2,volatile在使用时不会发生上下文切换或者线程调度操作。

  3.3,锁还有一个缺点是,当一个线程正在等待锁时,他不能做任何其他事情。
4,硬件对并发的支持

  4.1,堵占锁是一项悲观技术---它假设最坏的情况,并且只有在确保其他线程不会造成干扰的情况下才能执行下去。

  4.2,几乎所有的现代处理器中都包含某种形式的原子读-该-写指令,例如比较并交换或者关键加载/条件存储

  4.3,比较并交换,在大多数处理器架构中采用的方法是实现一个比较并交换(CAS)指令。CAS是一项乐观的技术,它希望能成功地执行更新操作,并且如果有另一个线程在最近一次检查后更新了该变量,那么CAS能检测到这个错误。当线程在竞争CAS失败时不会被挂起,而是告知这次竞争中失败,它不会阻塞线程,可以再次尝试或执行一些恢复操作。

  4.4,在大多数处理器上,在无竞争的锁获取和释放的“快速代码路径”上的开销,大约是CAS开销的两倍。CAS的主要缺点是,它将使调用者处理竞争问题(重试,回退,放弃),而在锁中能自动处理竞争问题(阻塞)。

  4.5,JVM对CAS的支持,在原子变量类(AtomicXxx)中使用这些底层的JVM支持的数字类型和引用类型提供一种高效的CAS操作,而在java.util.concurrent中的大多数类在实现时则直接或间接地使用了这些原子变量类。
5,原子变量类

  5.1,原子变量类不需要挂起或重新调度线程

  5.2,共有12个原子变量类,可分为4组:标量类,更新器类,数组类以及符合变量类

  5.3,原子变量类的标量类扩展了Number类,但没有扩展它们的包装类,
4000
基本类型的包装类时不可修改的,而原子变量类是可修改的,原子变量类中没有重新定义hashCode或equals方法

  5.4,原子变量是一种“更好的volatile”
  5.5,与CAS的算法一样,基于原子变量的compareAndSet的调度遇到竞争时立即重试,这将在激烈的竞争环境下导致更多的竞争。在中低程度竞争下,原子变量能够提供更高的可伸缩性,而在高强度的竞争下,锁能够更有效地避免竞争。

6,非阻塞算法

  6.1,如果一个算法中,一个线程的失败或挂起不会导致其他线程也失败或挂起,那么这种算法就被称为非阻塞算法,

  6.2,如果在算法的每个步骤中都存在某个线程能够执行下去,那么这种算法也被称为无锁(Lock-Free)算法

  6.3,如果算法中仅将CAS用于协调线程之间的操作,并且能够正确的实现,那么他既是一种无阻塞算法,又是一种无锁算法

  6.4,构建非阻塞算法的技巧在于:将执行原子修改的范围缩小到单个变量上

  6.5,原子的域更新器类(AtomicReferenceFieldUpdater)提供的原子性保证比普通原子类更弱一些,因为无法保证底层的域不被直接修改
7,ABA问题,指的是某个条件V首先由A变成B,再有B变成A。可以通过“”版本号“从而避免ABA问题。
8,非阻塞算法通过底层的并发原语来维持线程的安全性,这些底层的原语通过原子变量类向外公开,这些类也用作一种“更好的volatile变量”,从而为整数和对象引用提供原子的更新操作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: