问题描述

聊聊你对锁粗化和锁消除的理解。

个人回答

不会

知识整理

锁粗化

  1. public void method(String s1, String s2){
  2. synchronized(this){
  3. System.out.println("s1");
  4. }
  5. synchronized(this){
  6. System.out.println("s1");
  7. }
  8. }
  9. 编译后
  10. public void method(String s1, String s2){
  11. synchronized(this){
  12. System.out.println("s1");
  13. // }
  14. // synchronized(this){
  15. System.out.println("s1");
  16. }
  17. }

频繁的加锁解锁会导致资源消耗。为减少资源消耗,减少加锁解锁次数是一种途径。对于上面的代码来说。我一个方法中加解锁了2次。因此,编译器会自动将加锁解锁的范围放大。直接将两次打印包裹。这就是所谓的锁粗化。这样只需要加解一次锁即可

锁消除

  1. public static String createStringBuffer(String str1, String str2) {
  2. StringBuffer sb= new StringBuffer();
  3. sb.append(str1);// append方法是同步操作
  4. sb.append(str2);
  5. return sb.toString();
  6. }
  7. ————————————————
  8. 版权声明:本文为CSDN博主「我咋这么优秀呢」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  9. 原文链接:https://blog.csdn.net/zj57356498318/article/details/103364024

StringBufferappend()方法是一个同步方法,于是从我们的角度去看这个程序,会在每一次append()的时候都会进行一次加锁解锁操作。
而实际上,这段代码在实际执行时并没有加锁。这就是所谓的锁消除
对于sb来讲不会有别的线程去对它进行操作的。我这个线程调用这个方法新建的 sb 和别的线程调用这个方法所新建的sb。是两个sb。对于任意一个线程中的 sb ,不会有第二个线程去操作它。所以加锁是没有意义的。所以编译器就会将append()上的synchronized关键字去掉。就是不加锁。这就是所谓的锁消除。