2022年Java并发编程实践-电子书-章 .pdf
《2022年Java并发编程实践-电子书-章 .pdf》由会员分享,可在线阅读,更多相关《2022年Java并发编程实践-电子书-章 .pdf(8页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第八章 原子变量与非阻塞算法第八章原子变量与非阻塞算法 .18.1.8.2.8.3.锁的劣势 .2原子变量类 .2非阻塞算法 .5参考文献 .8名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - - 本章首先分析锁的劣势,然后分析原子变量类和非阻塞算法的优势。本章内容与第 3 章和第 4 章内容,紧密相关。相关内容情况参考前述章节。8.1.锁的劣势从前面的章节可以看到,使用一致的加锁协议来协调对共享状态的访问,确保当线程持有守护变量的锁
2、时,线程都能独占地访问这些变量,并且保证随后获得同一锁的线程都能看见该线程对变量所作的修改。Java 虚拟机能够对非竞争锁的获取和释放进行优化,让它们非常高效,但是如果有多个线程同时请求锁,Java 虚拟机就需要向操作系统寻求帮助。倘若了出现这种情况,一些线程将可能被挂起,并稍后恢复运行。从线程开始恢复,到它真正被调度前,可能必须等待其他线程完成它们的调度限额规定的时问。挂起和恢复线程会带来很大的开销,并通常伴有冗长的中断。对于基于锁,并且其操作过度细分的类(比如同步容器类,大多数方法只包含很少的操作),当频繁地发生锁的竞争时,调度与真正用于工作的开销间的比值会很可观。加锁还有其他的缺点。当一
3、个线程正在等待锁时,它不能做任何其他事情。如果一个线程在持有锁的情况下发生了延迟(原因包括页错误、调度延迟,或者类似情况),那么其他所有需要该锁的线程都不能前进了。如果阻塞的线程是优先级很高的线程,持有锁的线程优先级较低,那么会造成性能风险,被称为优先级倒置( priority inversion)。即虽然更高的优先级占先,但它仍然需要等待锁被释放,这导致它的优先级会降至与优先级较低的线程相同的水平。如果持有锁的线程发生了永久性的阻塞(因为无限循环、死锁、活锁和其他活跃度失败),所有等待该锁的线程都不会前进了。即使忽略上述的风险,加锁对于小的操作而言,仍然是重量级(heavy weight)的
4、机制,比如自增操作。需要有更好的技术用来管理线程之问的竞争。在Java 5.0 中,使用原子变量类( atomic variable classes )能够高效地构建非阻塞算法。8.2.原子变量类在 JDK 5.0 之前,如果不使用本机代码,就不能用Java 语言编写无等待、名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页 - - - - - - - - - 无锁定的算法。在java.util.concurrent 中添加原子变量类之后,这种情况发生了变化。本节了解
5、这些新类开发高度可伸缩的无阻塞算法。java.util.concurrent.atomic 包中添加原子变量类。所有原子变量类都公开“ 比较并设置 ” 原语(与比较并交换类似),这些原语都是使用平台上可用的最快本机结构(比较并交换、加载链接/条件存储,最坏的情况下是旋转锁)来实现的。原子变量类共有12 个,分成4 组:计量器、域更新器(field updater)、数组以及复合变量。最常用的原子变量是计量器:AtomicInteger、 AtomicLong、AtomicBoolean 以及AtomicReference。他们都支持CAS(比较并设置 ,详细参考第 3 章); AtomicIn
6、teger 和 AtomicLong 还支持算术运算。原子变量类可以认为是volatile 变量的泛化,它扩展了volatile 变量的概念,来支持原子条件的比较并设置更新。读取和写入原子变量与读取和写入对volatile 变量的访问具有相同的存取语义。虽然原子变量类表面看起来与SynchronizedCounter 例子(参考3.2.1 节)一样,但相似仅是表面的。在表面之下,原子变量的操作会变为平台提供的用于并发访问的硬件原语,比如比较并交换。调整具有竞争的并发应用程序的可伸缩性的通用技术是降低使用的锁对象的粒度,希望更多的锁请求从竞争变为不竞争。从锁转换为原子变量可以获得相同的结果,通过
7、切换为更细粒度的协调机制,竞争的操作就更少,从而提高了吞吐量。下面的程序是使用原子变量后的计数器:package jdkapidemo; import java.util.concurrent.atomic.AtomicInteger; publicclass AtomicCounter private AtomicInteger value = new AtomicInteger(); publicint getValue() returnvalue.get(); publicint increment() returnvalue.incrementAndGet(); publicint i
8、ncrement(int i) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 8 页 - - - - - - - - - returnvalue.addAndGet(i); publicint decrement() returnvalue.decrementAndGet(); publicint decrement(int i) returnvalue.addAndGet(-i); 下面写一个测试类:package jdkapidemo; publicclass At
9、omicCounterTest extends Thread AtomicCounter counter; public AtomicCounterTest(AtomicCounter counter) this. counter = counter; Override publicvoid run() int i = counter.increment(); System.out.println(generated number: + i); publicstaticvoid main(String args) AtomicCounter counter = new AtomicCounte
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年Java并发编程实践-电子书-章 2022 Java 并发 编程 实践 电子书
限制150内