Java基础之synchronized & volatile

b站地址:https://www.bilibili.com/video/BV1tz411q7c2
https://www.bilibili.com/video/BV1xK4y1C7aT?from=search&seid=2269221721031516085

synchronized & volatile

问题如下

在这里插入图片描述

需要学习的知识

在这里插入图片描述

CAS

在这里插入图片描述

追查源码,最终到jvm的unsafe.cpp下,
在这里插入图片描述
而sychronized 轻量级锁实现是cas,底层是lock ;cmpxchg指令。cmpxchg硬件底层指令是没用原子性的,也就是说,可能在更新值得过程中将其他的线程更新值覆盖,但是加上lock表示,不允许其他cpu的相关操作。
volatile则底层是lock; addl.

java对象的组成部分

markword,类指针,对象的属性,padding

markword包括哪些信息

1.锁信息,2.GC信息,3.identify hashcode(唯一标识符)

  • 64位
    在这里插入图片描述

用代码查看锁的信息。

    public static void main(String[] args) throws Exception{
        //sleep(5000);
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        synchronized (o)
        {
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }

打印结果

在这里插入图片描述
001表示的是处于无锁的状态,后面的000则是偏向锁。
如果把sleep(5000)注释打开,即休眠5s。
在这里插入图片描述

锁升级过程

在这里插入图片描述

在这里插入图片描述

volatile

1.防止指令重排序
2.保证线程可见性

happen-before就是一种规定,这些执行情况 不允许指令重排序。
比如 volatile修饰规则,join规则,线程start规则,传递规则,对象锁规则。
详情:https://blog.csdn.net/hanchao5272/article/details/79575491
as-if-serial规则就是,当发生指令重排时,必须保证,和串行发生一样。

在这里插入图片描述
load就是读,store就是写。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
JVM层面看的话,是加了 ACC_VOLATILE,设定对volatile修饰的变量需要前后加内存屏障再访问或者修改,
屏障的底层是是通过 lock ; addl 指令(编译语言层面)实现,意思可以理解为暂时锁住总线,不允许其他的线程直接访问内存,总之就是保证读到的内存数据是一致的,写可以导致其他高速缓冲区数据失效,读屏障可以要求cpu去内存读。

超线程

在这里插入图片描述

引用类型

强引用,比如Object o = new Object();,o指向堆中的Object对象,o就是强引用,垃圾回收时一定不会进行回收。
软引用:在内存不足时回收
弱引用:每次垃圾回收都会进行回收。
虚引用:用于堆外的内存回收。
https://www.cnblogs.com/gudi/p/6403953.html
在ThreadLocal中使用的就是弱引用,大致的图结构如下:
代码:
在这里插入图片描述
注意使用完需要调用remove方法,防止内存泄漏。
大致结构:

在这里插入图片描述
使用弱引用的原因是防止内存泄漏,key是一个ThreadLocal对象 ,每次set的时候就new一个继承了WeakReference的Entry,并且将key传给父类(WeakReference),使一个弱引用指向ThreadLocal对象,当tl引用消失,垃圾回收时就会自动回收ThreadLocal对象,但是在ThreadLocalMap中的值不会消失,所以为了防止内存泄露,需要再次调用remove方法。

书籍推荐

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章