juc-4-synchronized原理
创始人
2024-05-01 00:33:44
0

目录

1、synchronized 作用于静态方法

 总结

​编辑

  案例 静态成员变量 (synchronized锁非静态方法)

  案例 静态成员变量 (synchronized锁静态方法 或 直接锁类)

2、监视器锁(monitor)

2.1 synchronized怎么实现的线程安全呢?

3、JDK6 synchronized 的优化

   3.1 CAS讲解

3.2 synchronized

3.2.1 java对象的布局

 3.2.2 偏向锁

 3.2.3 偏向锁的撤销 

3.2.4轻量级锁(自旋锁/自适应自旋锁)


1、synchronized 作用于静态方法

 总结

  1.  当synchronized作用于静态方法时,其锁就是当前类的class对象锁。由于静态成员不专属于任何一个实例对象,是类成员,因此通过class对象锁可以控制静态 成员的并发操作。
  2.  synchronized作用于非静态方法时,也可以直接锁类。也可以控制静态 成员的并发操作。
  3.  synchronized作用于非静态方法时,必须是同一个对象才能控制静态 成员的并发操作。

需要注意的是如果一个线程A调用一个实例对象的非static synchronized方法,而线程B需要调用这个实例对象所属类的静态 synchronized方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的class对象,而访问非静态 synchronized 方法占用的锁是当前实例对象锁

  案例 静态成员变量 (synchronized锁非静态方法)

   synchronized修饰非静态方法时,锁的是当前实例,不同实例就不是同一把锁了,就不是线程安全 

public class ThreadRunnable5 implements Runnable {private static int a = 100;@SneakyThrows @Overridepublic void run() {while (true) {if (a > 1) {increase4Obj();Thread.sleep(100);}}}public synchronized   void increase4Obj(){System.out.println(Thread.currentThread().getName() + "==" + a);a--;}public static void main(String[] args) {ThreadRunnable5 thread = new ThreadRunnable5();new Thread(thread).start();new Thread(thread).start();}
}

 

  普通方法锁的就是 对象的实例,不同的实例对象时,就是两个锁。无法保证线程安全

  案例 静态成员变量 (synchronized锁静态方法 或 直接锁类)

2、监视器锁(monitor)

一篇就够,synchronized原理详解_小派师兄的博客-CSDN博客_synchronized原理

2.1 synchronized怎么实现的线程安全呢?

2.1 我们反编译下面的代码,看看jvm底层是如何帮助我们实现的线程安全的。

代码

public class ThreadRunnable6  {private static Object obj=new Object();public synchronized void test(){System.out.println("test打印");}public static void main(String[] args) {synchronized (obj){System.out.println("同步代码块");}}
}

执行反编译命令

到目标类的文件夹下
cd target/classes/com/example/juc/create/
对目标类执行命令
javap -p -v -c ThreadRunnable6.class

 找到main方法那段就行

jvm虚拟机规范文档找到指令作用

Chapter 6. The Java Virtual Machine Instruction Set

monitorenter内部结构

可以参考这个博客的一些理解,画的很容易理解,但是也不是很全面

Java并发编程之Monitor工作原理(有图解)_Juice正在路上..的博客-CSDN博客_java monitor原理

java对象头的总体结构,MarkWord的结构、MarkWord和锁的关系_时间都用来泡馍了的博客-CSDN博客_java对象头结构

获取锁资源的流程:

monitor是重量级锁

jvm底层调用会用到内核函数。需要我们由用户态切换到内核态。

那什么是内核态呢?为什么不能直接使用呢?

 我们的应用程序在内存运行的空间叫 用户空间(用户态)。

 它不能直接调用系统的硬件资源,会去损坏我们的硬件(随意删除内存数据,造成死机等)。为了安全,

只有内核能够调用硬件,应用程序靠系统调用,cpu由用户态转为内核态,调用完成后,操作系统会重置cpu为用户态并返回系统调用的结果。  

用户态与内核态来回切换会有大量的系统资源消耗,所以jdk1.6优化了synchronize 。

例如:IO操作,就需要内核态

3、JDK6 synchronized 的优化

   3.1 CAS讲解

跟乐观锁类似,本地内存和主存比较一样即可修改,内存地址和旧的预期值一样 就可以更改 成员变量 。do while用的很好

   

3.2 synchronized

jdk1.6做的优化,无锁---偏向锁---轻量级锁----重量级锁

3.2.1 java对象的布局

对象头:hash码,锁信息(判断是哪种锁状态,重量级锁的指针 moniter位置),gc标志

实例数据:类中属性数据信息,包括父类的属性信息;

对齐数据:jvm分64位和32位, 64位就是8字节,一个对象要被8整除。不够的补齐。

 3.2.2 偏向锁

总结:锁对象结构,一个线程使用的时候,就会是偏向锁,但是有四秒延时,四秒前打印不是偏向锁,四秒后就是偏向锁。

有偏向锁的原因:经过HotSpot作者发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由一个线程多次获取,为了让线程获取锁的代价更低,引入了偏向锁。

偏向锁:会偏向于第一个获取锁的线程,会在对象头存储偏向的线程id。以后该线程进入和退出同步快时只需要检查是否为偏向锁,锁标志位以及ThreadID即可。

偏向锁的基本流程图

步骤二是用CAS保证记录线程id的正确性。

 验证打印对象头信息

        org.openjdk.joljol-core0.9
    private static Object obj=new Object();public static void main(String[] args) {synchronized (obj){System.out.println(ClassLayout.parseInstance(obj).toPrintable());}}

 为什么打印的不是101(偏向锁)?

偏向锁在java1.6是默认启动的,但是要在程序启动后4秒才能激活。可以使用参数关闭延时。如果程序所有锁基本都要处于竞争状态也可以关闭偏向锁。

//关闭延迟开启偏向锁
-XX:BiasedLockingStartupDelay=0
//禁止偏向锁
-XX:-UseBiasedLocking

 3.2.3 偏向锁的撤销 

场景:两个线程竞争的时候就会去撤销偏向锁。

1偏向锁的撤销动作必须等待全局安全点(所有的线程都停下来了)

2暂停拥有偏向锁的线程,判断锁对象是否处于被锁定的状态。

3撤销偏向锁,恢复到无锁(标志位为01)或轻量级锁(标志位为00)的状态

3.2.4轻量级锁(自旋锁/自适应自旋锁)

场景:适用于多个线程交替去获取锁,而不是大量并发去获取锁。

jdk1.4引入自旋锁,1.6引入自适应自旋锁。 如果线程过多很多线程空耗cpu资源。升级为重量级锁(monitor

还有很多细节,实在学的难受,暂时放放。

偏向锁、轻量级锁、自旋锁、重量级锁,看这一篇就够了!_51CTO博客_自旋锁和互斥锁

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...