当前位置: 首页 > 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"…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...