当前位置: 首页 > news >正文

2_并发编程同步锁(synchronized)

并发编程带来的安全性同步锁(synchronized)

1.他的背景

当多个线程同时访问,公共共享资源的时候,这时候就会出现线程安全,代码如:

public class AtomicDemo {int i=0;//排他锁、互斥锁public  void incr(){  //synchronizedi++;    //i++最终3条指令 [线程安全问题中原子性]}public static void main(String[] args) throws InterruptedException {AtomicDemo ad=new AtomicDemo();Thread[] thread=new Thread[2];for (int i = 0; i <2 ; i++) {thread[i]=new Thread(()->{ for(int k=0;k<10000;k++) {   ad.incr();   } });thread[i].start();}thread[0].join();thread[1].join();System.out.println("Result:"+ad.i);}
}
//执行结果:17986,如果加上synchronized同步锁后结果为20000.
Result:17986

图片解析过程:

在这里插入图片描述

2.基本使用

synchronized有三种方式来加锁,不同的修饰类型,代表锁的控制粒度:

  1. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
  2. 静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
  3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁
public class SynchronizedDemo {//修饰实例方法public synchronized void m1(){  }Object lock=new Object(); //在内存中会分配一个地址来存储public void m2(){//代码块synchronized (lock){ } //lock为锁对象,也表示控制锁的范围}//静态方法public synchronized static void m3(){}
}
3.注意事项

锁的范围: synchronized中的锁对象如果是,普通对象这为当前对象锁,如果是静态类为全局锁。

4.底层原理

4.1 synchronized是如何实现锁的,以及锁的信息是存储在哪里?锁的信息是存储在锁对象下Markword对象头里的

4.2 在Hotspot虚拟机中,对象在内存中的存储布局,可以分为三个区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)

在这里插入图片描述

4.3 mark-word:对象标记字段占4个字节,用于存储一些列的标记位,比如:哈希值、轻量级锁的标记位,偏向锁标记位、分代年龄等

在这里插入图片描述

4.5 偏向锁状态[默认情况下,偏向锁的开启是有个延迟,默认是4秒 -XX:BiasedLockingStartupDelay=0] 为什么这么设计呢?

因为JVM虚拟机自己有一些默认启动的线程,这些线程里面有很多的Synchronized代码,这些
Synchronized代码启动的时候就会触发竞争,如果使用偏向锁,就会造成偏向锁不断的进行锁的升级和撤销,效率较低.

5.技术关联性

关于Synchronized锁的升级
jdk1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
锁主要存在四中状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,他们会随着竞争的激烈而逐渐升级。

这么设计的目的,其实是为了减少重量级锁带来的性能开销,尽可能的在无锁状态下解决线程并发问
题,其中偏向锁和轻量级锁的底层实现是基于自旋锁,它相对于重量级锁来说,算是一种无锁的实现

在这里插入图片描述

如果有线程去抢占锁,那么这个时候线程会先去抢占偏向锁 [也就是把markword的线程ID改为当前抢占锁的线程ID的过程] ----》

如果有线程竞争,这个时候会撤销偏向锁,升级到轻量级锁 --》

如有线程超过自旋,升级到重量级锁 [有线程超过10次自旋(-XX:PreBlockSpin参数配置),或者自旋线程数超过
CPU核心数的一般,在1.6之后,加入了自适应自旋Adapative Self Spinning. JVM会根据上次竞争的情况来自动控制自旋的时间]


轻量级锁的获取及原理

<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version>
</dependency>//-------------------------------public class Demo {Object o=new Object();public static void main(String[] args) {Demo demo=new Demo(); //o这个对象,在内存中是如何存储和布局的。System.out.println(ClassLayout.parseInstance(demo).toPrintable());synchronized (demo){System.out.println(ClassLayout.parseInstance(demo).toPrintable());}}
}结果:00 00 (00000001 00000000 00000000 00000000) (1)  无锁d5 02 (11011[000] 11110000 11010101 00000010) (47575256) 轻量锁

它的锁的标记是轻量级锁呢?

默认情况下,偏向锁的开启是有个延迟,默认是4秒。为什么这么设计呢?
因为JVM虚拟机自己有一些默认启动的线程,这些线程里面有很多的Synchronized代码,这些
Synchronized代码启动的时候就会触发竞争,如果使用偏向锁,就会造成偏向锁不断的进行锁的升级和
撤销,效率较低

偏向锁的获取及原理

通过下面这个JVM参数可以讲延迟设置为0.
-XX:BiasedLockingStartupDelay=0

public class Demo {Object o=new Object();public static void main(String[] args) {Demo demo=new Demo(); //o这个对象,在内存中是如何存储和布局的。System.out.println(ClassLayout.parseInstance(demo).toPrintable());synchronized (demo){System.out.println(ClassLayout.parseInstance(demo).toPrintable());}}
}
结果:
00 00 (00000101 00000000 00000000 00000000) (5)   偏向锁
4a 03 (00000101 00110000 01001010 00000011) (55193605) 偏向锁

重量级锁的获取

public static void main(String[] args) {Demo testDemo = new Demo();Thread t1 = new Thread(() -> {synchronized (testDemo){System.out.println("t1 lock ing");System.out.println(ClassLayout.parseInstance(testDemo).toPrintable());}});t1.start();synchronized (testDemo){System.out.println("main lock ing");System.out.println(ClassLayout.parseInstance(testDemo).toPrintable());}
}结果:
8a 20 5e 26 (10001010 00100000 01011110 00100110) (643702922)   重量锁
8a 20 5e 26 (10001010 00100000 01011110 00100110) (643702922)   重量锁
6.CAS

就是比较并交换的意思。它可以保证在多线程环境下对于一个变量修改的原子性。
CAS的原理很简单,包含三个值当前内存值(V)、预期原来的值(E)以及期待更新的值(N)。

相关文章:

2_并发编程同步锁(synchronized)

并发编程带来的安全性同步锁(synchronized) 1.他的背景 当多个线程同时访问&#xff0c;公共共享资源的时候&#xff0c;这时候就会出现线程安全&#xff0c;代码如&#xff1a; public class AtomicDemo {int i0;//排他锁、互斥锁public void incr(){ //synchronizedi; …...

Python 常用模块pickle

Python 常用模块pickle pickle序列化模块 【一】定义 序列化&#xff1a;将数据结构或对象转换为可存储或传输的格式反序列化&#xff1a;将序列化后的数据恢复为开始的数据结构或者对象 【二】目的 数据持久化存储远程通信缓存进程间通信 【三】序列化 将对象转换为字节…...

CentOS 6 制作openssh 9.6 p1 rpm包(含ssh-copy-id、openssl) —— 筑梦之路

openssh 9.6 需要openssl 1.1.1 以上版本&#xff0c;因此需要先安装openssl 1.1.1&#xff0c;可阅读这篇升级更新openssl版本到1.1.1w CentOS 6 制作openssl 1.1.1w rpm包 —— 筑梦之路-CSDN博客 CentOS 6很久都停止更新和支持&#xff0c;关于此版本的写的不多&#xff…...

Tomcat Notes: Deployment File

This is a personal study notes of Apache Tomcat. Below are main reference material. - YouTube Apache Tomcat Full Tutorial&#xff0c;owed by Alpha Brains Courses. https://www.youtube.com/watch?vrElJIPRw5iM&t801s 1、Tomcat deployment1.1、Two modes of …...

某邦通信股份有限公司IP网络对讲广播系统挖矿检测脚本

目录 1.漏洞概述 2.影响版本 3.危害等级 4.挖矿程序检测 5.Nuclei自动化检测...

uniapp点击跳转传对象

目录 传对象传对象传送组件接受组件 最后 传对象 传对象 传送组件 点击传给组件 <view class"dki-tit-edit" click"gotificatedit(item)">编辑 </view>gotificatedit(item){console.log(item,item);let options JSON.stringify(item);uni.…...

简单用PHP实现微信小程序的游戏功能

微信小程序的兴起&#xff0c;越来越多的开发者开始关注如何在小程序中实现游戏功能。PHP作为一种流行的后端语言&#xff0c;可以很好地与小程序进行搭配&#xff0c;实现游戏功能。下面将介绍如何使用PHP来实现微信小程序的游戏功能&#xff0c;并提供具体的代码示例。 建立…...

某查查请求头参数加密分析(含JS加密算法与Python爬虫源码)

文章目录 1. 写在前面2. 请求分析3. 断点分析4. 扣加密JS5. Python爬虫代码实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff…...

免费用chatGPT

免费用chatGPT&#xff0c;地址&#xff1a; DocGPT - 第二大脑...

还不会python 实现常用的数据编码和对称加密?看这篇文章就够啦~

相信很多使用 python 的小伙伴在工作中都遇到过&#xff0c;对数据进行相关编码或加密的需求&#xff0c;今天这篇文章主要给大家介绍对于一些常用的数据编码和数据加密的方式&#xff0c;如何使用 python 去实现。话不多说&#xff0c;接下来直接进入主题&#xff1a; 前言 1…...

简易实现 MyBatis 底层机制

MyBatis 大家好呀&#xff01;我是小笙&#xff0c;我中间有1年没有更新文章了&#xff0c;主要忙于毕业和就业相关事情&#xff0c;接下来&#xff0c;我会恢复更新&#xff01;我们一起努力吧&#xff01; 概述 MyBatis 是一个持久层的框架&#xff08;前身是 ibatis&#x…...

PhpPythonC++圆类的实现(OOP)

哎......被投诉了 &#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d; 其实也不是小编不更&#xff0c;这不是期末了吗&#xff08;zhaojiekou~~&#xff09;&#xff0c;而且最近学的信息收集和ctf感觉好像没找到啥能更的&#xff08;不过最经还是在考虑更一…...

OpenSSL升级版本

1 查看openssl版本 $ openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 目前是1.0版本系列. 2 下载最新稳定版本的OpenSSL源码包 $ wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz 3 编译源码安装 tar -xzvf openssl-1.1.1q.tar.gz cd openssl-1.1.1q .…...

基于sprinmgboot实习管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;实习管理也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而实习管理…...

图像分类任务的可视化脚本,生成类别json字典文件

1. 前言 之前的图像分类任务可视化&#xff0c;都是在train脚本里&#xff0c; 用torch中dataloader将图片和类别加载&#xff0c;然后利用matplotlib库进行可视化。 如这篇文章中&#xff1a;CNN 卷积神经网络对染色血液细胞分类(blood-cells) 在分类任务中&#xff0c;必定…...

Adding Conditional Control to Text-to-Image Diffusion Models——【代码复现】

官方实现代码地址&#xff1a;lllyasviel/ControlNet: Let us control diffusion models! (github.com) 一、前言 此项目的使用需要显存大于8G&#xff0c;训练自己的ControlNet或需要更大&#xff0c;因此请注意查看自身硬件是否符合。 在此之前请确保已经安装好python以及…...

java-Exchanger详解

1.概述 java.util.concurrent.Exchanger。这在Java中作为两个线程之间交换对象的公共点。 2.Exchanger简介 Exchanger类可用于在两个类型为T的线程之间共享对象。该类仅提供了一个重载的方法exchange(T t)。 当调用exchanger时&#xff0c;它会等待成对的另一个线程也调用它…...

‘再战千问:启程你的提升之旅‘,如何更好地提问?

例如&#xff0c;很多时候我们提出一些问题&#xff0c;然而通义千问提供的答案&#xff0c;并非完全符合我们的期望。这并非由于通义千问的智能程度不足&#xff0c;而是提问者的“提问技巧”尚未掌握得当。 难道提问还需要讲究艺术性吗&#xff1f;确实如此。今天&#xff0c…...

java SSM社区文化服务管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM社区文化服务管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的 源代码和数据库&#xff0c;系统主…...

go执行静态二进制文件和执行动态库文件

目的和需求&#xff1a;部分go的核心文件不开源&#xff0c;例如验证&#xff0c;主程序核心逻辑等等 第一个想法&#xff0c;把子程序代码打包成静态文件&#xff0c;然后主程序执行 子程序 package mainimport ("fmt""github.com/gogf/gf/v2/os/gfile"…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

41道Django高频题整理(附答案背诵版)

解释一下 Django 和 Tornado 的关系&#xff1f; Django和Tornado都是Python的web框架&#xff0c;但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架&#xff0c;鼓励快速开发和干净、实用的设计。它遵循MVC设计&#xff0c;并强调代码复用。Django有…...