第13章 线程安全与锁优化

线程安全

Java语言中的线程安全

我们可以将java语言中各种操作共享的数据分为以下5类:

  1. 不可变:1 final关键字修饰的变量(没有发生this引用逃逸的情况);2 Java.lang.String类的对象,调用它的方法是只会返回一个新构造的字符串对象;3 枚举类型;4 Long和Double等数值包装类型;
  2. 绝对线程安全:Java API中标注自己是线程安全的类,大多数都不是绝对的线程安全;
  3. 相对线程安全:相对的线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的。Vector、HashTable、Collections的synchronizedCollection()方法包装的集合等都属于这种类型;
  4. 线程兼容;
  5. 线程对立;
线程安全的实现方法
1. 互斥同步

Java中,最基本的互斥同步手段就是synchronized关键字。首先synchronized同步块对同一条线程来说是可以重入的,不会出现自己把自己锁死的问题;其次,同步块在已进入的线程执行完之前,会阻塞后面其他线程的进入。

除了synchronized之外,我们还可以使用java.util.concurrent包中的重入锁(ReentrantLock)来实现同步。

ReentrantLock增加的高级功能:

  1. 等待可中断
  2. 可实现公平锁
  3. 锁可以绑定多个条件
2. 非阻塞同步
3. 无同步方案
  1. 可重入代码
  2. 线程本地存储

锁优化

  1. 自旋锁与自适应自旋
  2. 消除锁
  3. 锁粗化
  4. 轻量级锁
  5. 偏向锁