Java并发编程实践
电子工业出版社
读书笔记:
1、volatile变量理解
写入volatile变量时就像退出同步块,读取volatile变量时就像进入同步块。volatile变量使用也存在好多限制,它通常被当作完成、中断、状态的标记使用。volatile变量只保证可见性,但不保证原子性。所以自增操作就不能依赖volatile,除非只有一个线程对它进行写操作。
不能用于构建原子化的复合操作,这意味着当一个变量依赖其他变量时,或者当变量的新值依赖于旧值时,是不能用volatile变量的。
2、可重进入的理解(Reentrancy)
当一个线程请求其他线程已经占有的锁时,请求线程会被阻塞。然而内部锁是可重进入的,因此线程在试图获得自己占有的锁时,请求会成功。重进入意味着锁的请求是基于“每线程的”,而不是“每调用的”。重进入的实现是通过为每个锁关联一个请求计数和一个占有它的线程。当计数为0时,认为锁是未被占有的。线程请求一个未被占有的锁时,JVM将记录锁的占有者,并且将请求计数置为1.如果同一线程再次请求这个锁,计数将递增;每次占用线程退出同步快,计数递减,到0锁就释放。
3、Collections.synchronizedMap() 和 ConcurrentHashMap的区别
它们一样是一个哈希表,但采用了不同的锁策略:前者使用公共锁同步每一个方法,并严格的限制只有一个线程能访问容器。后者采用一个更加细化的锁机制,名叫分离锁。
前者同步提供了一个特性就是为独占的访问加锁,这在后者中并没有实现。这对于一些罕见的情况是必要的,例如原子的加入一些mapping,或者对元素进行若干次迭代,在这期间需要看到元素以相同的顺序出现。
4、CopyOnWriteList/CopyOnWriteSet 写入时复制(copy on write)原理解析
"写入时复制"容器的线程安全性来源于这样一个事实,只要有效的不可变对象被正确的发布,那么访问它将不再需要更多的同步。在每次需要修改时,它们会创建并重新发布一个新的容器拷贝,以此来实现可变性。"写入时复制"容器保留一个底层基础数据的引用。这个数组作为迭代器的起点,永远不会被修改,以尼茨对它的同步只不过为了确保数组内容的可见性。它返回的迭代器与创建时保持一致,不会考虑后续的修改。
适合对容器迭代的频率远远高于对容器修改的频率。
5、阻塞队列 与 生产-消费者模式
阻塞队列接口 BlockQueue 支持两个附加操作的Queue,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用。
BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:
| 抛出异常 | 特殊值 | 阻塞 | 超时 |
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
移除 | remove() | poll() | take() | poll(time, unit) |
检查 | element() | peek() | 不可用 | 不可用 |
它的实现:LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列
PriorityBlockingQueue是按照优先级顺序排序的队列
SynchronousQueue它根本不是一个真正的队列,因为它不会队列元素维护任何存储空间,不过它维护一个线程清单。适合消费者充足的情况,它们总能为下一个任务做好准备。
6、双端队列和窃取工作
Java 6同样新增了两个容器类型,Deque(发音为deck)和BlockingDeque,它们分别扩展了Queue和BlockingQueue。Deque是一个双端队列,允许高效地在头和尾分别进行插入和移除。实现它们的是ArrayDeque和LinkedBlockingDeque。
双端队列使它们自身与一种叫做窃取工作的模式相关联。在窃取工作的设计中,每一个消费者都有一个自己的双端队列。如果一个消费者完成了自己双端队列中的全部工作,它可以偷取其他消费者的双端队列中的末尾任务,这样可以保持每个线程都保持忙碌的状态。
7、延迟周期执行工具:Timer和新的ScheduledThreadPoolExecutor的比较
在JDK5或者更高的版本中,不建议使用Timer。
原因分析:
Timer对调度的支持是基于绝对时间的,而不是相对时间的,由此任务对系统时钟的改变是敏感的;而ScheduledThreadPoolExecutor只支持相对时间。
Timer只创建唯一的线程来执行所有的Timer任务。
Timer还有一个问题在于,如果TimerTask抛出未检查的异常,Timer将产生无法预料的行为。Timer线程并不捕获异常,所以TimerTask抛出的未检查异常会终止Timer的执行,而且Timer也不会再重新恢复线程的执行,它错误的认为整个Timer都被取消了。
分享到:
相关推荐
读书笔记-Java并发编程实战-基础篇
《Java并发编程实战》个人读书笔记,非常详细: 1 简介 2 线程安全性 3 对象的共享 4 对象的组合 5 基础构建模块 6 任务执行 7 取消与关闭 8 线程池的使用 9 图形用户界面应用程序 10 避免活跃性危险 11 性能与可...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括可见性、发布与逸出、线程封闭、不可变性、安全发布等内容
java并发编程的艺术读书笔记根据章节整理的核心内容,便于自己理解
《java并发编程实战》读书笔记-第2章-线程安全性,脑图形式,使用xmind8制作 包括引言、线程安全性定义、原子性、加锁机制、使用锁保护状态、活跃性与性能等内容
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括线程安全类设计、实例封闭、线程安全性委托、现有线程安全类中添加功能和文档化同步策略等内容
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括同步容器类、并发容器类、阻塞队列和生产者消费者模式、阻塞和中断方法、同步工具类。最后是构建高效且可伸缩的结果缓存
Java编程思想(第4版)读书笔记by CZFJava编程思想(第4版)读书笔记by CZFJava编程思想(第4版)读书笔记by CZF
《Java并发编程实践》一书的个人读书笔记。主要列举包括各个章节的关键知识点,便于反复阅读和知识复习掌握。
SpringBoot项目学生读书笔记共享系统是一个为学生、教师和书籍爱好者设计的网络应用程序,旨在提供一个便捷的读书笔记共享与管理平台。该系统通过集成用户注册、笔记上传、标签管理、内容搜索和社区互动等功能,实现...
java并发源码集合
本人十余年JAVA从业经验,擅长JAVA高可用、分布式、高并发系统架构设计。有志于做JAVA系统性的技术提升的同学可与我联系,交个朋友哦~ 本人十余年JAVA从业经验,擅长JAVA高可用、分布式、高并发系统架构设计。有志...
loveincode's notes 学习工作中的一些记录,收藏。 操作系统 , 编译原理 , 计算机网络 , 互联网协议... 常用数据结构与算法 Java 实现 数据结构 与 排序算法 ...读书笔记 Effective Java , HTTP权威指南 , Java
读书笔记 Java Core :处于萌芽阶段的 Java 核心知识库。 :bar_chart: :crossed_swords: :desktop_computer: :bus_stop: :beach_with_umbrella: :foggy: :postbox: :magnifying_glass_tilted_left: :rocket: :...
2020读书笔记 介绍 项目收集自己阅读的书籍笔记,以后后续查阅快速定位(在GitHub图片不能正常显示,应该是我网速原因,所以链接都是gitee,GitHub也会有一样的文件) 环境: Typora + idea + Java11 + CentOS7(虚拟机) + ...
读书笔记和示例代码 包括 线程基础/同步sync/并发concurrent/容器/线程池 示例代码 JUC容器的源码解析 Synchronized 同步容器 Concurrent 并发容器: Map/List/Queue 阻塞队列 JUC锁: CountDownLatch 闭锁 AQS 锁的...
word源码java OfferFighting 9月完成 数据结构(日常) 浙大网课+浙大教材 Java代码表示数据结构03 数据结构/my-offer/...Java高并发 看书 7:00-8:00 剑指offer刷题 直接刷 8:00--11:00 Java基础不专门做笔记
interview面试所需的读书笔记,知识点及收集的面试问题。其中包含对以下书籍的知识点摘录:、部分内容由于备战校招期间太忙,没记录笔记子项目内容algorithm 算法练习concurrent 并发笔记design 设计模式笔记...
读书笔记,摘要读书过程中的知识要点和想法感悟 纸函 优秀的博客文章,三人行必有我师 万藏 收集便捷好用的开发工具,以及收集的一些文档资料 :red_heart: :yellow_heart: :green_heart: :blue_heart: :purple_heart...