有些东西,不写下来了,时间长了,就忘了~
—谨记逝去的那份技术记忆
这次是读第二遍了,相比第一遍,读起来熟练了很多,技术细节也能有点想法了,期待更进一步吧
除了《ava核心技术》和《Thinking in java》,java程序员更应该看看这本书,而且java并发编程的很多知识点和罗列的问题和我们学习过的“操作系统”是一致的,而且市面上凡是涉及到java和线程内容的,讲述的内容和这本书都很相似,只是市面上其他书更加粗略罢了。
下面把自己抄录的东西罗列一下,省的忘了。
- Date自身是可变的
- 线程安全类的设计:
确定对象状态是由哪些变量构成
确定限制状态变量的不变约束
指定一个管理并发访问对象状态的策略- 类的同步策略应该写入文档
- 遍历同步容器可能存在ConcurrentModificationException,单线程中也会出现这样问题,遍历的时候,在容器中删除元素
- 隐藏的迭代,容器的hashcode和equals方法会间接调用迭代
- 并发容器
jdk5.0添加了ConcurrentHashMap代替Map,CopyOnWriteArrayList代替List,Queue和PriorityQueue(这个不是并发的),BlockingQueue,ConcurrentLinkedQueue;JDK1.6添加了ConcurrentSkipListMap代替SortedMap,ConcurentSkipListSet代替SortedSet关于ConcurrentHashMap:
- 同步容器类在每个操作的执行期间都持有一个锁。所以Map.get或者List.contains存在大量工作,equals被大量使用,本身有需要大量计算,hashcode要保证很好的分散韩细致,保证元素均匀分布在容器中,
- 很差的哈希函数会把一个哈希表转换为一个线性链表,遍历很长的清单并调用其中部分或者整体的equals方法,会花费很长时间,由于同步类容器的锁策略,在这段时间内,其他线程都不能访问这个容器
- 以前的Map实现是使用了一个公共锁同步每一个方法,并且严格限制只有一个线程可以同时访问容器。
- ConcurrentHashMap,使用了分离锁,实现的性能上几乎没有损失
- ConcurrentHashMap返回的迭代器具有弱一致性(允许容器并发修改),而非以前的“及时失败”。
- concurrenthashMap采取了并发环境下的size和isEmpty的弱化,size返回的是一个近似值而非精确值,但是优化了put、get、containsKey和remove
- Hashtable和SynchronizedMap都采用了独占的访问加锁,都是同步Map
- !ConcurrentHashMap不能在独占访问中加锁
关于BlockingQueue
可阻塞的put和take方法,与可定时的offer、poll等价,支持生产者=消费者设计模式,
具体实现由ArrayBlockingQueue、LinkedBlockingQueue (都是FIFO队列)、PriorityBlockingQueue (优先级队列)、SynchronousQueue (没有存储能力)- executor的无法正确关闭,会阻止JVM的正常结束
- 关于Amdahl定律 P225 、Little定律 P232
- JVM要在初始化期间获得一个锁,这个锁每个线程都会至少用到一次,来确保一个类是否已经被加载过,这个锁也保证了静态初始化期间,内存的写入结果自动的对所有线程是可见的
- 双检查锁反模式 P379,作者反对双重检查锁反模式,在《设计模式之禅》中讲到了使用静态内部类实现单例模式的懒加载机制,可以参见这个,原理见上面那一条
- SynchronousQueue不是一个真正的队列,而是一种管理直接在线程间移交信息的机制,只有当池是无限的或者可以接受任务被拒绝,SychrinousQueue才是一个有价值的选择
- 任务执行框架,简化任务和线程生命周期的管理,提供简便、灵活的方式,可以在任务的提交和任务的执行策略之间解耦
- ReentrantLock 和 Semaphore 的比较P306
一些好的例子:
- 支持关闭的ServSocket p122
- 关于图片的并发下载机制
- 关于日志服务
- 注册关闭钩子
- 有限缓存使用显示的条件变量 P209
- 使用lock实现信号计数量 P310
- AQS 二院闭锁 P313
学到的新技能
- 获取cpu的数目: Runtime.getRuntime().avaulableProcessors()
- 快排是和处理大数据集合,冒泡适合处理小数据集合。(特别大的话,就得用上hadoop和spark了)
- -XX:+DisableExplicitGC 忽略system.gc的调用,-verbose:gc 垃圾回收根本不会执行,-XX:PrintCompilation 在动态编译运行时打印出信息
- 使用FindBugs静态分析工具
还有一些不知道怎么表达,自己还需要深入学习。