线程安全性

当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。线程安全的核心在于访问共享的可变状态时需要进行正确的管理。

如何保证线程安全

使用不可变对象

如果某个对象在被创建后其状态就不能被修改,则该对象成为不可变对象。不可变对象只具有一种状态,且该状态由构造函数控制。(无状态对象指不包含任何域和任何对其它对象中域的引用的对象)
当满足以下条件时,对象才是不可变对象:

  1. 对象创建后其状态就不能修改
  2. 对象的所有域都是final类型
  3. 对象是正确创建的(对象创建期间,this引用没有逸出)

注:从技术上来说,域不一定非要是final。只要对类的良性数据竞争情况做精确分析,保证域值在对象创建之后不会被修改即可,例如String。

线程封闭

仅在单线程内访问数据,就不需要同步。这就是线程封闭技术,它是实现线程安全性的最简单的方法之一。单线程内访问数据,这个数据即可以是局部变量,可以是某些在单一线程中访问的数据(比如说Swing中的可视化组件和数据模型对象只能在事件线程中被访问)也可以是同一时间只能由一个对象访问的数据(比如JDBC中的Connection对象。线程从连接池中获得一个Connection对象来处理请求,使用完之后再返还给线程池。在上一个线程返还之前,线程池不会再将这个对象分配给其它线程)。
线程封闭是程序设计中的考虑因素,必须由程序来实现。Java提供了一些机制来帮助维持线程封闭(例如局部变量和ThreadLocal类,但仍需要程序员确保封闭在线程中的对象不会从线程中逸出)
Ad-hoc线程封闭
栈封闭
ThreadLocal类

加锁保证同步

使用锁来保证有状态对象的一致性。(这一部分比较复杂,看了一些资料,感觉理解比较肤浅,不全面,没想清楚实质,后续再补充)