第二章 线程安全性

2.1 什么是线程安全性

  当多个线程访问某个类,这个类始终表现出正确的行为,称这个类是线程安全的。

  线程安全类:无状态类

  完全由线程安全类组成的程序不一定是线程安全的,线程安全类中也可以包含非线程安全的类。

2.2 原子性

  一系列操作不可分。

  2.2.1 竞态条件

  不恰当的执行顺序出现不正确的结果,这一情况称为竞态条件。

  类型之一:先检查后执行。大多数的竞态条件出现的原因是出于可能失效的观察结果作出决定。

  2.2.3 复合操作

  将全部的复合操作交由线程安全对象执行保证安全性。

  延伸:无状态类中添加一个线程安全成员对象,仍然是线程安全的。

2.3 加锁机制  

  不变性条件涉及多个变量,仅保证每个变量都是线程安全对象是无用的。需要将对所有变量的操作封装在一个原子操作中。

  2.3.1 内置锁

  java提供了同步代码块保证范围加锁。同步代码块由两部分组成:加锁的对象和加锁区间    

synchronized(lock){
    //线程安全操作区间
}
同步代码块

  每个java对象都可以当成锁(对象头中的锁状态标识)。这种锁称为内置锁,获取锁的线程进入代码块,退出代码块释放锁。

  用同一个对象当锁锁住多个代码块,统一时间只能获取其中一个的访问权限。

//锁对象
private Object lock;

synchronized(lock){
    //代码A
}

synchronized(lock){
    //代码B
}
多个锁区间

  2.3.2 重入

  内置锁可以重入。子类改写父类的同步方法,两者是一个锁管理。

2.4 锁保护状态

  锁保护状态的更改和读取,保证访问的串行。(指广义的锁概念)

2.5 活跃性和性能

  加锁限制并发性,只在必要情况和范围内加锁,细心维护加锁的粒度。

人生就像蒲公英,看似自由,其实身不由己。
原文地址:https://www.cnblogs.com/walker993/p/14585178.html