【JUC】二十七、synchronized锁升级之无锁

2023-12-13 21:28

本文主要是介绍【JUC】二十七、synchronized锁升级之无锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1、背景
  • 2、Monitor、Java对象、线程如何关联起来的?
  • 3、synchronized锁升级
  • 4、锁升级之无锁

关于synchronized同步,能用无锁结构就不要用锁;能锁块,就不要锁整个方法;能用对象锁,就不要用类锁。

在这里插入图片描述
用锁能够保证数据的安全性,但性能下降。无锁,性能提升,但安全性下降,如何平衡?

1、背景

在Java早期版本,synchronized是重量级锁,效率低下,因为监视器锁monitor依赖底层操作系统的Mutex Lock(系统互斥量)来实现。

Java5之前,用户态和内核态之间的切换:
在这里插入图片描述

用户态和内核态之间切换指的是:

Java的线程是映射到操作系统的原生线程之上的(Java的start方法底层是native start0方法),因此阻塞和唤醒一个线程都需要操作系统介入去切换CPU的状态来完成(内核态),这种状态切换需要耗费处理器的时间,如果同步代码块很简单,那切换的时间可能比代码执行时间还长。

而用户态和内核态有各自专用的内存空间、专用的寄存器 ⇒ 因此,用户态切换到内核态还需要传递很多变量和参数过去,且内核也要去维护这些值。

鉴于以上,Java6后,引入轻量级锁和偏向锁,别一下就捅到重量级锁。一句话,为了尽量减少用户态和内核态的切换次数。

2、Monitor、Java对象、线程如何关联起来的?

如果一个Java对象被某线程锁住,则:

  • 该Java对象的Mark Word中的Lock word指向monitor的起始地址
  • Monitor的__Owner字段会存放拥有这个对象锁的线程的 id

在这里插入图片描述
在这里插入图片描述

关于Monitor的复习:【Monitor】

Monitor是在JVM底层实现的,底层代码是c++。本质是依赖于底层操作系统的Mutex Lock实现,而Mutex Lock 的切换需要从用户态转换到内核态中,因此状态转换需要耗费很多的处理器时间,所以synchronized在Java中是一个重量级操作。

3、synchronized锁升级

synchronized锁升级主要依赖Mark Word中锁标志位和释放偏向锁标志位。

在这里插入图片描述

  • 偏向锁:MarkWord存储的是偏向的线程ID

  • 轻量锁:MarkWord存储的是指向线程栈中Lock Record的指针

  • 重量锁:MarkWord存储的是指向堆中的monitor对象的指针

4、锁升级之无锁

无锁:即初始状态,一个对象被实例化后,如果还没有被任何线程竞争锁,那它就是无锁状态(001)

在这里插入图片描述
用JOL展示下,一个对象在无锁状态下,其对象头是如何记录的。

Object object = new Object();
//hashcode方法是native的,调用了才会生成,否则为0
System.out.println("10进制:" + object.hashCode());
System.out.println("16进制:" + Integer.toHexString(object.hashCode()));
System.out.println("2进制:" + Integer.toBinaryString(object.hashCode()));
System.out.println(ClassLayout.parseInstance(object).toPrintable());

结果分析:前25位是没使用的unUsed,再往后31位是hashcode,倒着看

在这里插入图片描述

这篇关于【JUC】二十七、synchronized锁升级之无锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/490016

相关文章

将Mybatis升级为Mybatis-Plus的详细过程

《将Mybatis升级为Mybatis-Plus的详细过程》本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现... 目录说明流程增加依赖修改配置文件注释掉MyBATisConfig里面的Bean代码生成使用IDEA生

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

linux环境openssl、openssh升级流程

《linux环境openssl、openssh升级流程》该文章详细介绍了在Ubuntu22.04系统上升级OpenSSL和OpenSSH的方法,首先,升级OpenSSL的步骤包括下载最新版本、安装编译... 目录一.升级openssl1.官网下载最新版openssl2.安装编译环境3.下载后解压安装4.备份

怎么关闭Ubuntu无人值守升级? Ubuntu禁止自动更新的技巧

《怎么关闭Ubuntu无人值守升级?Ubuntu禁止自动更新的技巧》UbuntuLinux系统禁止自动更新的时候,提示“无人值守升级在关机期间,请不要关闭计算机进程”,该怎么解决这个问题?详细请看... 本教程教你如何处理无人值守的升级,即 Ubuntu linux 的自动系统更新。来源:https://

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

macOS升级后SVN升级

问题 svn: error: The subversion command line tools are no longer provided by Xcode. 解决 sudo chown -R $(whoami) /usr/local/Cellar brew install svn

关键字synchronized、volatile的比较

关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。随着JDK新版本的发布,synchronized关键字的执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。多线程访问volatile不会发生阻塞,而synchronize

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑

JeecgBoot 升级springboot版本到2.6.0

1. 环境描述 Jeecgboot 3.0,他所依赖的springboot版本为2.3.5Release,将springboot版本升级为2.6.0。过程全纪录,从2开始描述。 2. 修改springboot版本号 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-pare

欧拉系统 kernel 升级、降级

系统版本  cat  /etc/os-release  NAME="openEuler"VERSION="22.03 (LTS-SP1)"ID="openEuler"VERSION_ID="22.03"PRETTY_NAME="openEuler 22.03 (LTS-SP1)"ANSI_COLOR="0;31" 系统初始 kernel 版本 5.10.0-136.12.0.