第四章 现代并发(二)
一 现代并发应用程序的构件
java.util.concurrent包 包含大量编写多线程代码的工具
1 原子类:java.util.concurrent.atomic
其中有几个名字以Atomic打头的类 语义基本和volatile一样 封装在一个API中 包含为操作提供的适当的原子(要么不做,要做就全做)方法。是非常简单的避免再共享数据上出现竞争危害的办法
常见用法是实现序列号机制 再AtomicInteger或AtomicLong上用原子操作getAndIncrement()方法
此类有个nextId()方法 每次调用时肯定能返回唯一一个并且完全增长的数值 和数据库里序列号的概念很像
2 线程锁:java.util.concurrent.locks
1)快结构同步方式基于锁这样一个简单的概念 这个方式有几个缺点
锁只有一种类型
对被锁住对象的所有同步操作都是一样的作用
在同步代码块或方法开始时取得线程锁
在同步代码块或方法结束时释放线程锁
线程或者得到锁 或者阻塞——没有其他可能
2) 如果我们要重构对线程锁的支持 有几处可以提升
添加不同类型的锁,比如读取锁和写入锁
对锁的阻塞没有限制 即允许在一个方法中上锁 在另一个方法中解锁
如果线程得不到锁 比如锁由另外一个线程持有 就允许该线程后退或继续执行 或者做点别的事情——运用tryLock()方法
允许线程尝试取锁 并可以在超过等待时间后放弃
实现以上的关键就是locks类中的Lock接口 和它的两个实现类
ReentrantLock——本质上跟用在同步块上那种锁是一样的 但稍微灵活些
ReentrantReadWriteLock——在需要读取很多线程而写入很少线程时 用它较好
3 CountDownLatch
一种简单的同步模式,这种模式允许线程在通过同步屏障之前做些少量的准备工作
4 ConcurrentHashMap
是标准HashMap的并发版本 提供了多线程的安全性 并且性能更优
5 CopyOnWriteArrayList
是标准ArrayList的替代品 通过增加写时复刻(copy-on-write)语义来实现线程安全性
6Queue
java中有些多线程编程模式在很大程度上都依赖于Queue实现的线程安全性
队列经常用来在线程之间传递工作单元,这个模式通常适合用Queue最简单的并发扩展BlockingQueue来实现
1)BlockingQueue
两个特性
在向队列中put()时 如果队列已满 它会让放入线程等待队列腾出空间
在从队列中take()时 如果队列为空 会导致取出线程阻塞
2)使用工作单元
Queue接口全部是泛型的——Queue<E> 等等