Java并发编程实战(二)-线程安全性

要编写线程安全的代码,核心在于要对状态访问操作进行管理,特别是共享的(shared)可变的(mutable)状态的访问。

对象的状态是指存储在状态变量中的数据,可能包括依赖对象的域。

“共享”意味着变量可以由多个线程同时访问;“可变”意味着变量的值在其生命周期内可以发生变化。

一个对象是否需要是线程安全的,取决于它是否被多个线程访问,而不是对象要实现的功能。

修改线程不安全代码的方法:

1.不再线程间共享该变量的状态(封闭线程)

2.将状态变量修改为不可变的

3.在访问变量状态时使用同步

在设计代码的初期就应该考虑线程安全的问题

2.1什么是线程安全性

无状态变量一定是线程安全的

2.2原子性

2.2.1竞态条件

由于不恰当的执行时序而出现不正确的结果,也即当某个计算的正确性取决于多个线程交替执行的时序时,那么就会发生竞态条件

2.2.2示例:延迟初始化中的竞态条件

2.2.3复合操作

“先检查后执行”和“读取-修改-写入”等操作统称为符合操作:包含了一组必须以原子方式执行的操作以确保线程安全性

在实际的情况中,应尽可能的使用先用现有的线程安全的对象来管理状态。

2.3加锁机制

当不变性的条件中涉及多个变量时,各个变量之间不是彼此独立的,当一个变量更新,需要在同一个原子操作中对其他变量同时进行更新

2.3.1内置锁

使用同步代码块的锁就是方法调用所在的对象,静态的synchronized方法以Class对象作为锁

2.3.2重入

锁传递,不会由于锁竞争产生死锁

2.4用锁来保护状态

对于可能被多个线程同时访问的可变状态变量,在访问它时都需要持有同一个锁,在这种情况下,我们称状态变量是由这个锁保护的

2.5活跃性与性能

锁将降低代码的性能,所以需要在简单性和性能之间寻找一个最佳的平衡

 

posted @ 2014-04-07 14:39  peiyuc  阅读(187)  评论(0)    收藏  举报