如何做到线程安全

什么是线程安全

可变资源(内存)线程间共享

如何实现线程安全

  • 不共享资源(ThreadLocal)
  • 共享不可变资源(可重入函数)
  • 对于共享可变资源,需要:1、 可见性;2、操作原子性;3、禁止重排序

ThreadLocal

ThreadLocal本质上是一个绑定到Thread中的Map(ThreadLocalMap),Map的key为ThreadLocal对象本身,value为需要存入的值。

ThreadLocal的使用建议:

  • 声明为全局静态final成员
  • 避免存储大量数据
  • 用完后及时移除对象

禁止重排序

  • 在重排序的情况下,final的成员变量会在构造方法中赋值,而非finial的成员变量可能会在构造方法外才被赋值(所以说final有禁止重排序的功能)。

  • Volatile 让对象保证线程可见,禁止重排序。

保证线程可见性

  • final
  • volatile
  • 加锁,当锁释放时会强制将缓存刷新到主内存

保证原子性

  • 加锁,保证操作的互斥性
  • 使用原子数值类型(AtomicInteger, …)
  • 使用原子属性更新器(AtomicRefrenceFieldUpdater)