- 介绍
- 线程的优点
- 使用多处理器。这是多核的时代。
- 模型的简化。有些应用模型就是需要并发处理,如servlet,一个内置的多线程功能,可以很好的匹配这种模型,并且不需要考虑诸如任务的创建、切换、负载均衡等细节问题。
- 对异步事件的简单处理。单线程环境下,对于一些可以导致阻塞的任务,如socke.read,需要使用异步事件的机制,这使得实现起来复杂得多。而多线程很多时候可以解决这类问题。
- 没有多线程的GUI,容易由于某一个事件完成时间长,而导致界面冻洁。
- 线程的风险
- 安全风险。 并发处理共享变量时,容易导致意外的执行结果。
- 活跃度的危险。 死锁、饥饿、活锁等。
- 性能危险。 上下文切换导致的性能开销。
- 线程的优点
基础
线程安全。
线程安全,关键在于“正确性”,这意味着一个类与它的规约保持一致,通常可简单认为在多线程环境下不会比单线程环境下有更多的隐患。
线程安全的代码本质就是:
管理对状态的访问,并且通常是共享的、可变的状态。
一个对象的状态就是它的数据,包含了任何会对它的外部可见行为产生影响的数据。
共享是指一个变量可以被多个线程访问。
可变是指其生命周期内可以被改变。当多线程访问一个类时,如果不用考虑这些线程在运行环境下的调度和交替执行,并且不需要额外的同步及调用方代码不必作其他的协调,这个类的行为仍然正确的,那么称这个类是线程安全的
无论何时,只要多于一个线程访问给定的状态变量,而且其中某个线程会写入该变量,此时必须使用同步来协调线程对变量的访问。
原子性
- 竞争条件(race codition)
- 当正常性依赖于运行时的时序时,会产生竞争条件
- 常见:读-改-写 (read-modify-write),检查-运行(check-then-act)
- 如 单例的LazyInit
- ref:数据竞争(data race)
- 锁
为了保护状态的一致性,要在单一的原子操作中更新相互关联的状态变量
- 内部锁 ssynchronized ,每一个java对象都可以当作一个内部锁(intrinsic lock),或监控器锁(monitor lock)
- 重入锁(reentryncy)
- 是per-thread 而非 per-invocation。 通过记录计数器和占用线程实现
- 锁策略
每个共享的可变变量都需要由唯一一个确定的锁保护,而维护者应用清楚这个锁。
对于每一个涉及多个变量的不变约束,需要同一个锁保护其所有的变量
- 活跃度与性能
通常简单性与性能之间是互联牵制的。实现一个同步策略时,不要过早地为了性能而牺牲简单性。
有些耗时的计算或操作,比如网络或控制台I/O,难以快速完成,执行这些操作期间,不要占用锁。
- 竞争条件(race codition)
共享对象
- 可见性。
- 重排序。在单个线程里,只要重排序对结果不会产生影响,那么不能保证程序按写定的顺序执行。这是为了更好的利用CPU的性能。 但是多线程环境下,确可能产生不良影响。
只要数据被跨线程共享,就进行恰当的同步
过期数据
非原子的64位操作。 64位数据,double和long是非原子的,jvm允许将其读或写划分为两个32位操作。所以有可能出现读的一值的高32位和另一个值的低32位。因而,一般作为共享变量时,申请为volatile或用锁保护起来民,以保证其可见性。
volatile。保证可见性,并且不会被重排序。
用于确保它们所引用的对象状态的可见性,或者用于标识重要的生命周期事件的发生。
发布和逸出
- 发布 一个对象的意思是使它能被当前范围之外的代码所引用
- 逸出 是指一个对象在尚未准备好的时候就将它发布
线程封闭。
- 将对象封闭在某一个线程,如ThreadLocal或JDBC线程池Connect
- ad-hoc
- 栈限制
- ThreadLocal
不可变性
- 不可变对象总是线程安全的
- final域。 保证域值的不可为,并且保证初始化安全性。
- 满足以下条件,才是不可变:
- 它的状态不能在创建后再被修改
- 所有域都是final类型,并且
- 它被正确创建(创建期间没有发生this引用逸出)
安全发布
- 一个正确创建的对象可以通过以下条件安全地发布:
- 通过静态初始化器初始化对象的引用
- 将它的引用存储到volatile域或AtomicReference
- 将它的引用存储到正确创建的对象的final域中
- 或者将它的引用存储到由锁正确保护的域中
- 一个正确创建的对象可以通过以下条件安全地发布:
- 可见性。
3.组合对象
1. 不变约束,后验条件,先验条件 2. 不理解对象的**不变约束**和**后验条件**,你就不能保证线程安全,要约束状态变量的有效或者状态转换,就需要原子性与封闭性。构建并发应用程序
- 活跃度、性能和测试
- 高级主题
复述
- 一句话:
这是以javaSE5、6为原型讲并发编程的原理和实践的书