关于Synchronized的小结

news2024/7/5 22:49:36

目录

一.特性

1.既是乐观锁又是悲观锁

2.是轻量级锁,也是重量级锁 

 3.不是读写锁,是互斥锁

4.是可重入锁

5.非公平锁

6.加锁之后,运行完毕自动解锁释放资源

 二:Synchronized使用

第一种:定义一个额外的变量来控制加锁和解锁(类似于吉祥物)

第一种:直接给类/方法上锁

三.synchronized的优化

运行机制上的优化

 编译阶段进行的优化手段

锁消除

程序员代码上进行优化

锁粗化


一.特性

1.既是乐观锁又是悲观锁

乐观锁:就是在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断在此期间别的线程有没有更新过这个数据。

悲观锁:就在操作数据时比较悲观,每次去拿数据的时候认为别的线程也会同时修改数据,所以每次在拿数据的时候都会上锁,这样别的线程想拿到这个数据就会阻塞直到它拿到锁。

2.是轻量级锁,也是重量级锁 

偏向锁:单线程情况下,第一个使用锁,就升级为偏向锁

轻量级锁:多线程下,第二个线程来同一个线程竞争同一个资源,这个时候偏向锁升级为轻量级锁(竞争很小)

重量级锁:超级多线程同时来竞争一个资源(竞争非常激烈),这个时候由轻量级锁升级为重量级锁

 3.不是读写锁,是互斥锁

读写锁:多线程下,同一时刻只能有一个线程读取这份资源,其他线程不能读取处于阻塞

互斥锁:多线程下,同一时刻只能有一个线程使用这份资源,其他线程不能使用处于阻塞

4.是可重入锁

可重入锁:在两个带锁的线程中,当前线程1的锁没被解锁的情况下,能够去执行带有锁的线程2

不可重入锁:在两个带锁的线程中,当前线程1的锁没被解锁的情况下,不可以去执行带有锁的线程2

5.非公平锁

公平锁:多线程下,当锁被线程1释放后,线程2,3,4依据自己谁先请求资源的时间先后获取该资源,进行上锁操作

非公平锁:多线程下,当锁被线程1释放后,不管时间请求的顺序先后,线程2,3,4各凭本事抢占该资源,进行上锁操作

6.加锁之后,运行完毕自动解锁释放资源

自动释放:Synchronized的代码执行完毕之后,不用调用解锁的代码,就能自动解锁释放资源

非自动释放:与Synchronized当对应的有个叫做ReentrantLock的锁,ReentrantLock就是调用之后,必须要程序员手动输入"解锁指令"来关闭

 二:Synchronized使用

第一种:定义一个额外的变量来控制加锁和解锁(类似于吉祥物)

public class demo2 {
//定义一个Object类,名字叫做lock的变量作为锁
    static  Object lock = new Object();
     public static void main(String[] args) {
         synchronized (lock){
         }
    }
}

第一种:直接给类/方法上锁

//给类上锁
public class demo2 {
    synchronized public static void main(String[] args) {
        
    }
}




//给方法上锁
public class demo2 {
    synchronized static void  func(){
        System.out.println("hello");
    }
     public static void main(String[] args) {
    }
}

三.synchronized的优化

运行机制上的优化

无->偏向锁->轻量级锁->重量级锁

注意:在轻量级锁这里synchronized,采用[自适应自旋锁]

自旋锁:一直不停反复查看当前锁是否被释放,一旦释放,自己就立刻占为己有,为期上锁

自适应自旋锁:重复一定次数/一定时间后,停止查看

 编译阶段进行的优化手段

锁消除

锁消除:编译器+JVM会检测当前代码是否是多线程执行,是否有必要加锁,如果没有必要,在编写的时候又把锁给写上了,就会在编译过程中自动把锁去掉。

列如StringBuffer,他每次apped操作都是需要加锁和解锁,如果只有简单的append操作的话

 那么编译器就直接进行一次加锁和解锁,而不是多次加锁和解锁

程序员代码上进行优化

锁粗化

锁的粒度:synchronized代码块,包含代码的多少(代码越多,粒度越大 ;代码越少,粒度越细)。 

一般写代码的时候,多数情况下,是希望锁的粒度更小一点(串行执行的代码少,并发执行的代码就多)。串行代码越少越少,程序执行就越快。

 举一个例子

假如说你现在需要向领导汇报三个工作

你可以选择,分三次汇报三个不同的工作

或者选择,一次汇报三个工作

显然,我们是更倾向于一次汇报三个工作的,因为他更高效

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/676505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】MySQL备份与恢复

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 MySQL备份与恢复 一、数据备份的重要性1.数据库备份的分类2.常见的备份方法3.MySQL完全备份与分类 二、MySQL 日志管理三、MySQL 备份与恢复1.MySQL 完全备份1.物理冷备份与恢…

Linux 服务器以及各个系统下安装

Linux 服务器 Linux是操作系统: Linux作为自由软件和开放源代码软件发展中最著名的例子,背靠社区与商业化的使用,使其得到了广泛的应用与发展。 Linux无处不在: 世界上500个最快的超级计算机90%以上运行Linux发行版…

【MyBatis学习】动态SQL的使用,MyBatis还能这样使用?惊掉了我的下巴 ,赶快带着好奇心一起畅游动态SQL的海洋吧! ! !

前言: 大家好,我是良辰丫,今天我们来学习一下MyBatis中动态sql的使用,带着疑惑走进我们今天的学习! ! !💌💌💌 🧑个人主页:良辰针不戳 📖所属专栏:javaEE进阶篇之框架学习 🍎励志语句…

短视频矩阵源码开发部署技术解析

短视频矩阵源码开发涉及到多个方面的技术,包括但不限于以下几点: 抖yinAPI:需要通过API获取抖音的视频、用户、评论、点赞等数据。 抖yinSDK:如果需要开发一些原生的功能,比如分享、登录、支付等,需要使用…

深入解析大型语言模型:从训练到部署大模型

简介 随着数据科学领域的深入发展,大型语言模型—这种能够处理和生成复杂自然语言的精密人工智能系统—逐渐引发了更大的关注。 LLMs是自然语言处理(NLP)中最令人瞩目的突破之一。这些模型有潜力彻底改变从客服到科学研究等各种行业&#x…

【每天40分钟,我们一起用50天刷完 (剑指Offer)】第四天 4/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示&#…

Jenkins集成Sonar与Gitlab代码质量检测

前提默认 安装docker19,与docker-compose 安装Jenkins 1、docker-compose.yaml配置 version: 3 services: jenkins: #network_mode: "host" #镜像 image: jenkins/jenkins:2.399-jdk11 #容器名称 container_name: jenkins #启动模式 res…

探索uniapp+vue3解析markdown语法|uniapp键盘撑起

最近正在尝试使用uniappvue3开发仿制chatgpt会话功能。 如上图:经过测试在h5/App端/小程序端 均支持markdown语法解析,键盘撑起后,整体页面和顶部自定义导航栏不会被顶起。 uniapp markdown解析及语法高亮 使用了markdown-it和highlight.js…

深入理解深度学习——BERT(Bidirectional Encoder Representations from Transform):输入表示

分类目录:《深入理解深度学习》总目录 BERT在预训练阶段使用了《深入理解深度学习——BERT(Bidirectional Encoder Representations from Transform):MLM(Masked Language Model)》和《深入理解深度学习——…

C++——函数重载

目录 1. 函数重载的概念 2. 函数重载注意点 3. C可以函数重载的原因 4. 总结 1. 函数重载的概念 函数重载:是函数的一种特殊情况。C语言不支持函数重载,而C允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 …

【软件设计师暴击考点】软件工程知识高频考点【一】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:软件…

基于Springboot+vue的汽车租赁系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

阿里云服务器的可用区和地域选择有哪些考虑因素?如何优化性能?

阿里云服务器的可用区和地域选择有哪些考虑因素?如何优化性能?   选择阿里云服务器时,可用区和地域选择是一个非常关键的环节。本文将为您详细解析在这个过程中需要考虑的因素以及如何优化性能。 一、阿里云服务器的可用区和地域选择的考虑…

PHP基础知识解析:探索PHP编程的核心概念和技巧

目录 PHP简介 什么是PHP 网站基本概念 网站 静态网站特点 动态网站特点 服务器概念 IP 域名 DNS 端口 PHP基础知识 PHP语法 PHP注释 PHP语句分隔符 变量 变量基本概念 变量的使用 命名的命名规则: 预定义变量: 可变变量 变量传值 …

【Linux操作系统】共享内存

文章目录 什么是共享内存?共享内存的原理共享内存的知识点构建创建共享内存的前提-key值共享内存的创建ipcs命令共享内存的释放共享内存的关联与解除代码演示共享内存的大小共享内存的特点 什么是共享内存?共享内存的原理 共享内存让不同进程看到同一份…

C++ --引用与函高级

引用 定义:给变量起别名。 语法:数据类型&别名原名。 int a10; int &ba; //(此时的a和b都指向了同一块空间,都可对里面的元素进行修改) 对这两个变量名字任意一个进行修改,两变量的结果都会发生变化 引用注意事项 1.引…

211大学,4个计算机应届生,真实求职情况~

每年6月,毕业就业是一个绕不开的永恒话题!2024届秋招即将开始,你们都找到工作了吗?是否还在犹豫、焦虑、没有头绪…… 先知先觉的那一批人,总会未雨绸缪,从前辈那里汲取经验。 播妞采访了4位211计算机应届…

vue+leaflet笔记之地图放大镜

vueleaflet笔记之地图放大镜 文章目录 vueleaflet笔记之地图放大镜开发环境使用教程安装依赖库使用简介 详细源码(Vue3) 本文介绍了Web端使用 Leaflet开发库显示地图放大镜的方法 (底图来源:中科星图),结合 leaflet.magnifyingglass插件可以为Leaflet图层添加“放…

SHAP显示原始特征

1.问题描述 SHAP用于特征解释,对于机器学习方法往往需要对原始特征进行编码,而SHAP在绘制单个样本时,会显示每个特征及其取值,而这个取值已经是编码后的,通常无法确定其含义。如: 下图所示的拍卖公司、城市…

【软件设计师暴击考点】数据结构高频考点暴击系列

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:软件…