美文网首页
synchronized

synchronized

作者: designer | 来源:发表于2021-01-14 22:31 被阅读0次

实现过程

1.java 代码 synchronized
2.monitorenter moniterexit
3.执行过程中自动升级
4.lock comxchg

1. ABA问题

image.png

2.unsafe

底层实现 cmpxchg = cas 修改变量

lock cmpxchg

2.Object o = new Object() 在内存中占了多少个字节?(16个字节)

1.分为普通对象和数组对象


image.png

2.对象头为:markword和class pointer
3.实例数据 instance data
4.对齐 padding 当对象不能被8整除,则往上追加到能被8整除

image.png

64 位的JVM,则他的长度默认是64位即8个字节,由于启用了CompressClassPointer 压缩,则占用4个字节

3.synchronized 上锁,锁信息在markword上。

new (无锁) - 偏向锁 - 轻量级锁 -重量级锁

image.png

1.刚开始没人,然后先贴一个标签
2.有多个人了,然后抢占锁,把自己的Lock Record 记录到markdown上,则占坑成功,其他的通过CAS继续,自旋多次,超级损耗CPU,则自动升级重量级锁。
3.每一个重量级锁,会有一个队列,在队列里面等待,不占用任何CPU。

锁降级(不重要)

锁消除 lock eliminate

package com.java.sync;

/**
 * @Author: fql
 * @Email: fangqiulin4923@gmail.com
 * @Date: 2021-01-14 20:51
 */


public class T01 {

    public static void main(String[] args) {
//        AtomicInteger i = new AtomicInteger();
//        i.incrementAndGet();
        T01  t = new T01();
      System.out.println( t.add("sdd","dddd"));


    }

    public String add(String s1,String s2){
        StringBuffer sb = new StringBuffer();
        sb =  sb.append(s1).append(s2);
        return sb.toString();
    }
}

我们都知道Stringbuffer是线程安全的,因为它的关键方法都是被synchronized修饰过的,但我们看上面的代码,我们会发现,sb这个引用置灰在add方法中使用,不可能被其他线程引用(因为是局部变量,栈私有),因此sb不可能共享资源,JVM会自动消除StringBuffer 对象内部锁

锁粗化

image.png

JVM会检测到这样一连串的操作都对统一对象加锁(while 循环内100次执行append,没有锁粗化的就要进行100次加锁、解锁),此时JVM就会将加锁的范围粗化到这一连串的操作外部(比如while虚幻体外),是的这一连串操作只需要加一次锁即可。

相关文章

网友评论

      本文标题:synchronized

      本文链接:https://www.haomeiwen.com/subject/vqrbaktx.html