本文将对Java中并发编程的重难点作一定解释。
线程安全
无状态对象永远是线程安全的
无状态对象指的是没有成员域变量的对象
原子操作
自增操作是三个离散操作的简写形式: 获取当前值,加1,写回新值。这是一个读-改-写
操作的实例,其中,结果的状态衍生自它先前的状态。竞争条件
当计算的正确性依赖于运行时中的相关的时序或者多线程的交替时,会产生竞争条件;换句话说,想要得到正确的答案,要依赖于“幸运”的时序。最常见的一种竞争条件是检查再运行
,使用一个潜在的过期值作为决定下一步操作的依据。例如: 你观察到一些事情为真(文件X不存在),然后(then)基于你的观察去执行一些操作(创建文件X);但事实上,从观察到执行操作的这段时间内,观察结果可能已经失效了(有人在此期间创建了文件X),从而引发错误(非预期的异常,重写数据或者破坏文件)。复合操作和原子操作
假设有操作A和B,如果从执行A的线程的角度看,当其他线程执行B时,要么B全部执行完成,要么一点都没有执行,这样A和B互为原子操作。一个原子操作是指: 该操作对于所有的操作,包括它自己,都满足前面描述的状态。
java.util.concurrent.atomic 包中包括了原子变量类这些类用来实现数字和对象引用的原子状态转换。例如
long
类型替换为AtomicLong
类型。内部锁
Java提供了强制原子性的内置锁机制:synchronized
块。一个synchronized
块共有两部分: 锁对象的引用,以及这个锁保护的代码块。synchronized
方法是对跨越了整个方法体的synchronized
块的简短描述,至于synchronized
方法的锁,就是该方法所在的对象本身。synchronized (lock){ // 访问或修改被锁保护的共享状态 }
执行
synchronized
块的线程,不可能