当一个类的实例或者静态方法被并发使用的时候,这个类的行为如何,
- 是该类与客户端程序的行为约束
- 如果文档中没有相关描述,那么可能导致未同步或过度同步的情况
并不是说文档中出现Synchronized 就说明是线程安全
- synchronized 可能仅仅是实现细节
线程安全是分多种级别的:
- 一个类可以被多个线程安全的使用,必须在文档中清楚的说明其支持的安全级别
- 常见情形安全级别划分:
- 不可变:
- 实例是不可变的,不需要外部的同步
- 如:String、Long、BigInteger等
- 无条件的线程安全:
- 可变实例,内部拥有足够的同步,无需任何外部同步
- 如:Random、ConcurrentHashMap
- ConcurrentHashMap是线程安全的,
- 将Map 分成16个segment,
- 按照hash值对应key到某个segment
- 每个操作都是线程安全的
- ConcurrentHashMap是线程安全的,
- 有条件的线程安全:
- 非线程安全:
- 必须外部同步包围每个方法调用,才能正常使用
- 比如:ArrayList、HashMap
- 线程对立的
- 这个类不能安全的被多个线程并发调用,即使所有方法都被外部同步
- 出现这种问题的根源在于,没有同步修改静态变量
- 不可变:
公有同步锁、
- 允许客户端程序以原子形式执行一个方法调用序列
- 比如ConcurrentHashMap
私有同步锁
- 客户端无法访问锁
- 私有锁对象只能用到无条件线程安全类上
总结::
- synchronized 注释与该类是否线程安全毫无关系
- 无条件线程安全类,请使用私有锁来代替同步的方法
- 有条件的线程安全类,必须在文档标明哪个方法调用时需要外部同步