锁优化
一些提高锁的效率的策略
优化操作
主要是以编译器+JVM两者配合进行的
1、锁消除
锁消除本质是以编辑器和JVM代码运行的情况智能的判断当前的锁有没有必要加 如果没有必要, 就会直接把锁干掉
public class Demo3 {
public static void main(String[] args) {
//StringBuffer 是线程安全的方法中加了Sychronized关键字 StringBuilder是线程不安全
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("wade");
stringBuffer.append("wade");
stringBuffer.append("wade");
stringBuffer.append("wade");
//像这样的代码,每次执行都会涉及加锁和解锁操作.JVM判断后直接把锁消除
//事实上,当前的StringBuffer只是在一 个线程中使用,不涉及线程安全问题.
System.out.println(stringBuffer);
}
}
StringBuffer 是线程安全的方法中加了Sychronized关键字
2、偏向锁
- 第一个尝试加锁的线程 不会真正的加锁 而是进入偏向锁(一种很轻量的锁) 直到其他线程也来竞争这把锁的时候 才会取消偏向锁的状态 真正的进行加锁
比如我们网易云上听歌的时候,有的歌不火的时候,是不收费的,如果一旦火了,很多人来听,那突然就会要VIP才能听,就相当于加了锁。
总而言之上述这俩个优化机制就是能不加锁就不加锁
3、自旋锁
当有很多线程竞争锁的时候, 偏向锁状态被消除 此时没有得到锁的线程并不会直接直接挂起放弃 而是使用自旋锁 的方式来尝试去再次获取锁
比如我去健身 如果此时有一个人来和我竞争一个健身器材 我不会立马放弃 而是会约定一个时间稍微等会 时间到就换人 ,挂起等待的话就是这个人走了。
自旋锁能保证让其他想竞争锁的线程尽快获取到锁.付出了一定的CPU资源.
4、锁膨胀
- 当锁竞争更加激烈的时候 此时就会从自旋状态膨胀成重量级锁(挂起等待锁)
比如我去健身 如果此时很多人来和我竞争一个健身器材 , 竞争太激烈的时候短期内不能获取到器材,等待的人就会回家了,不练了
5、锁粗化
- 如果一段逻辑中需要多次加锁,解锁 并且在解锁的时候没有其他线程来竞争 此时就会把多组的锁操作合并在一起 (合并后的锁的粒度很比较粗 所以叫锁粗化)