Java中synchronized锁的深入理解

 更新时间:2023年05月29日 08:35:02   作者:舒一笑  
这篇本文主要对Java中synchronized锁进行深入理解,文中通过synchronized的优化,synchronized的实现原理及synchronized的升级过程来介绍Java中synchronized锁,感兴趣的同学可以跟着小编一起来学习

使用范围

  • synchronized使用上用于同步方法或者同步代码块
  • 在锁实现上是基于对象去实现
  • 使用中用于对static修饰的便是class类锁
  • 使用中用于对非static修饰的便是当前对象锁

synchronized的优化

  • 在jdk1.6中对synchronized做了相关的优化

锁消除

  • 在synchronized修饰的代码块中,要是不涉及操作临界资源的情况,即便你写了synchronized修饰,也不会出发锁机制

锁膨胀

  • 在一个循环中频繁的出现锁资源的获取与释放操作,会带来资源的消耗,于是便会将锁的范围扩大到循环的外边,避免频繁的竞争和获取锁资源而导致的资源消耗
  public void method(){
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            synchronized ("") {
                // 业务代码
            }
        }
    }

锁升级

  • ReentrantLock中是基于乐观锁的CAS获取线程资源。资源拿不到的情况下才会挂起线程。synchronized在jdk1.6之间完全获取不到锁的情况下立即挂起线程,但是在1.6之后进行了锁的升级与优化。
  • 无锁、匿名偏向:当前对象没有作为锁的存在
  • 偏向锁:当前锁资源,只有一个线程频繁的获取和释放锁,那么只有该线程获取锁是判断是否是同一个线程,如果是线程资源拿走。如果线程不是当前自己的线程,则采用基于CAS的方式,尝试将偏向锁指向当前线程。如果获取不到则触发锁升级为轻量级锁,也就意味着发生了锁竞争的情况。
  • 轻量级锁:使用自旋锁的方式频繁的采用CAS的方式获取锁资源。这里采用的自适应自旋锁(JVM更具上次的自旋结果来进行判断本次的自旋时间长短)。如果成功获取锁资源,资源取走。如果获取锁资源失败,锁升级。
  • 重量级锁:最为传统的synchronized实现方式。拿不到锁资源之间挂起线程,然后进行用户态和内核态的不断切换。。。

synchronized锁的实现原理

  • synchronized锁是基于对象来进行实现的

  • 关于MarkWord的内容展开示意图

  • 从图中可以看出通过锁的标志位来进行区分锁的不同状态

synchronized锁升级的过程演示

  • 使用之前需要导入一个依赖
<dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>

  • 锁在默认情况下,开启了偏向锁的延迟
  • 原因是因为在偏向锁升级为轻量级锁的时候会涉及到偏向锁的撤销,需要等到一个安全点(STW),才能完成对偏向锁的撤销,所以在并发的情况下就可以选择不开启偏向锁,或者设置偏向锁延迟开启
  • 在JVM启动时会大量加载.class文件到内存,该操作会涉及synchronized使用,为了避免出现偏向锁撤销的操作。在启动初期,有一个延迟5s开启偏向锁的操作。
  • 要是正常开启偏向锁,那么就不会出现无锁的状态,而是直接进入匿名偏向锁

  • 变成了偏向锁

/**
 * @author
 * @date 2023/5/28
 */
public class Test15 {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(5000);
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
		//thread 线程偏向锁
        Thread thread = new Thread(()->{
            synchronized (o){
                System.out.println("thread线程 :"+ClassLayout.parseInstance(o).toPrintable());
            }
        });
        thread.start();
        // 轻量级锁 -> 重量级锁
        synchronized (o){
            System.out.println("main线程 :"+ClassLayout.parseInstance(o).toPrintable());
        }
    }
}

锁转换状态示意图

LockRecord和ObjectMonitor存储的内容示意图

以上就是Java中synchronized锁的深入理解的详细内容,更多关于Java synchronized锁的资料请关注脚本之家其它相关文章!

相关文章

  • JavaWeb响应下载功能实例代码(包含工具类)

    JavaWeb响应下载功能实例代码(包含工具类)

    今天通过本文给大家分享的是关于javaweb的响应(response)下载功能,需要的朋友参考下吧
    2017-07-07
  • MyBatis的@SelectProvider注解构建动态SQL方式

    MyBatis的@SelectProvider注解构建动态SQL方式

    这篇文章主要介绍了MyBatis的@SelectProvider注解构建动态SQL方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java线程间共享实现方法详解

    Java线程间共享实现方法详解

    这篇文章主要介绍了Java线程间共享实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java多线程通信问题深入了解

    Java多线程通信问题深入了解

    下面小编就为大家带来一篇深入理解JAVA多线程之线程间的通信方式。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-07-07
  • Java使用split截取字符串过程解析

    Java使用split截取字符串过程解析

    这篇文章主要介绍了Java使用split截取字符串过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • IntelliJ IDEA基于Maven构建Java项目

    IntelliJ IDEA基于Maven构建Java项目

    在 Java 开发中,使用 Maven 是一种广泛采用的构建工具,本文主要介绍了IntelliJ IDEA基于Maven构建Java项目,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • IDEA引MAVEN项目jar包依赖导入问题解决方法

    IDEA引MAVEN项目jar包依赖导入问题解决方法

    这篇文章主要介绍了IDEA引MAVEN项目jar包依赖导入问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 关于Spring3 + Mybatis3整合时多数据源动态切换的问题

    关于Spring3 + Mybatis3整合时多数据源动态切换的问题

    这篇文章主要介绍了关于Spring3 + Mybatis3整合时多数据源动态切换的问题,需要的朋友可以参考下
    2017-04-04
  • jsp+dao+bean+servlet(MVC模式)实现简单用户登录和注册页面

    jsp+dao+bean+servlet(MVC模式)实现简单用户登录和注册页面

    这篇文章主要介绍了jsp+dao+bean+servlet(MVC模式)实现简单用户登录和注册页面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • SpringBoot自动装配原理详细解析

    SpringBoot自动装配原理详细解析

    这篇文章主要介绍了SpringBoot自动装配原理详细解析,一个对象交给Spring来管理的三种方式 @Bean @Compoment @Import,
    @Bean主要在@Configuration中,通过方法进行注入相关的Bean,@Compoent与@Service归为一类,在类上加注入对应的类,需要的朋友可以参考下
    2024-01-01

最新评论