JavaEE初阶-多线程进阶1

news2024/10/4 8:25:23

文章目录

  • 前言
  • 一、常见的锁策略
    • 1.1 乐观锁与悲观锁
    • 1.2 重量级锁与轻量级锁
    • 1.3 自旋锁与挂起等待锁
    • 1.4 可重入锁与不可重入锁
    • 1.5 公平锁与非公平锁
    • 1.6 互斥锁与读写锁
  • 二、synchronized的优化策略
    • 2.1 锁升级
    • 2.2 锁消除
    • 2.3 锁粗化


前言

多线程进阶的内容在面试中容易考,但是在工作开发中很少用到。


一、常见的锁策略

并非局限于java,其它变成语言或者其它系统级别的组件,但凡涉及到锁,都和接下来谈到的锁策略有一定关系。

1.1 乐观锁与悲观锁

加锁的时候要预测发生冲突的概率是大还是小,如果说加锁后预测冲突发生概率小,要做的善后工作少,加锁的开销小(时间、系统资源),那么这把锁就是乐观锁。如果说加锁后预测冲突发生概率大,要做的善后工作多,加锁的开销大(时间、系统资源),那么这把锁就是悲观锁。
那么java中的我们学过很多的synchronized是悲观锁还是乐观锁?
事实上synchronized既是悲观锁也是乐观锁,它是一种自适应的锁,它能够统计出当前锁冲突的次数,进行判定锁冲突的概率低还是高,当冲突概率高时就按照悲观锁的处理方式来执行(速度更快),当冲突概率低时就按照乐观锁的处理方式来执行(做的工作更多)。
乐观锁一般只涉及到用户态的操作,要做的工作少。悲观锁往往是要通过内核完成一些操作,要做的工作就多。

1.2 重量级锁与轻量级锁

加锁的过程做的多指的就是重量,加锁的过程中做的少就是轻量,因此一般来说乐观锁就是轻量级锁,悲观锁就是重量级锁,实际交流过程中这两组概念可能会混着用。

1.3 自旋锁与挂起等待锁

自旋锁是轻量级锁的一种典型的实现方式。
在这里插入图片描述
如图cpu在空转,陷入一种忙等的状态。通过消耗资源来确保第一时间获取到锁。
挂起等待锁是重量级锁的一种典型实现方式,借助系统的线程调度机制,当尝试加锁锁被占用了就会出现锁冲突,此时尝试加锁的线程就会被挂起(阻塞状态),此时这个线程就不会参与调度了。直到要加的锁被释放后,系统才会重新唤醒这个线程去重新获取锁。从这个过程可以看出,挂起等待是很慢的,因为线程一旦阻塞起来这个过程是不可控的,可能会经历很长的时间,但是这个方法对cpu的使用很少。
java中的synchronized轻量锁使用自旋锁实现(基于CAS机制实现),重量锁使用挂起等待锁实现(调用系统API,通过内核)。

1.4 可重入锁与不可重入锁

java中的synchronized就是可重入锁,一个线程,针对这把锁连续加锁两次不会产生死锁。不可重入锁就相反,针对一把锁连续加锁两次就会产生死锁。

1.5 公平锁与非公平锁

公平锁指的就是严格按照先来后到的顺序来获取锁,哪个线程等待的时间长就先得到锁。非公平锁就是指若干个线程各凭本事随机获取得到锁,这和线程的等待顺序无关,java中的synchronized就属于非公平锁。
这里不禁提出一个问题,什么叫公平?我按照先来后到的顺序是一种公平,我每个线程一起竞争得到锁的概率随机也不失为一种公平。这里其实涉及到历史的问题,因为设计这个概念的大佬就是这样描述公平锁的,所以我们也只能听大佬的了。

1.6 互斥锁与读写锁

互斥锁的概念比较简单,java中的synchronized就是互斥的。
读写锁是一个比较特殊的锁,我们之前学过数据库中的事务的隔离性里面给读加锁给写加锁,这里的读写锁跟那个不一样,在事务那里加锁降低了并发能力,但在这里加锁是为了提高并发能力。java中的读写锁是这样设定的:
(1)读锁和读锁不会产生互斥。
(2)写锁和写锁之间会产生互斥。
(3)读锁和写锁之间会产生互斥。
我在这里说一下我的理解,读写锁就是将锁细化了,当在多线程的情况下读取数据是不会产生线程安全问题的,因此读锁之间无需互斥,这样降低了锁冲突的概率从而提高了并发能力。相反在多线程的情况下写数据是有问题的,因此写锁之间需要互斥来保证线程安全。

二、synchronized的优化策略

synchronized既是悲观锁也是乐观锁,既是重量级锁也是轻量级锁,轻量级锁的实现基于自旋锁,重量级锁的实现基于挂起等待锁,是可重入锁,不是读写锁,是非公平锁。

2.1 锁升级

synchronized这种自适应锁的锁升级的过程如下图:
在这里插入图片描述
在这个过程中主要要理解一下偏向锁。
首次使用synchronized给对象进行加锁时不是真的加锁,而是做一个标记(非常轻量非常快,几乎没有开销),这就是偏向锁。如果一直没有别的线程尝试给这个对象加锁,那么就会一致保持这种偏向锁的状态直至释放解锁。(解锁也就是改变标记,也几乎没有开销)上述过程中就相当于没有任何加锁操作,速度非常快。但是如果在偏向锁的状态下也有别的线程尝试给该对象加锁,那么偏向锁就会立即升级为轻量级锁从而发生互斥保证线程安全。偏向锁就是“懒”这个字的具体体现,能不加锁就不加锁,能晚加锁就晚加锁,这样就能在很多时候把开销省下来。
上述的锁的升级过程对一个锁对象来说是不可逆的,只能升级不能降级。

2.2 锁消除

锁消除是一种编译器优化策略,你代码中有加锁操作,编译器以及JVM会对其进行判定,看这个地方是否真的需要加锁,如果不需要就会自动将加锁操作给优化掉。最典型的例子就是在一个线程内使用synchronized。编译器优化前和优化后的效果需要一致,所以这里是比较保守的,作用有限,本质上也是为了在程序员感知不到的情况下去提高效率。

2.3 锁粗化

首先了解一个概念就是锁粒度,指的就是在加锁的范围内包含的代码越多就认为锁的粒度越粗,反之就是锁的粒度越细。
锁的粗化也是一种优化策略,比如说有些逻辑中需要频繁的加锁,此时我们就可以进行锁的粗化,将多段逻辑包含到一个锁当中。
在这里插入图片描述

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

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

相关文章

解决SpringBoot整合MyBatis和MyBatis-Plus,请求后不打印sql日志

问题发现 在整合springBootmyBatis时,发现请求不打印sql日志,示例代码如下: RestController public class MyController {AutowiredProductMapper productMapper;GetMapping("/test")public void test() {System.out.println(&qu…

【知识碎片】2024_05_12

本篇记录了两个代码题【字符个数的统计】和【多数元素】(下有一段快排的代码)&#xff0c;以及两个关于数组的选择题。 每日代码 字符个数统计 字符个数统计_牛客题霸_牛客网 统计ascall码在0~127内的字符出现过几次&#xff08;重复出不再计算&#xff09; #include <st…

快速入门:利用Go语言下载Amazon商品信息的步骤详解

概述 在这篇文章中&#xff0c;我们将深入探讨如何利用Go语言这一强大的工具&#xff0c;结合代理IP技术和多线程技术&#xff0c;实现高效下载Amazon的商品信息。首先&#xff0c;让我们来看看为什么选择Go语言作为开发网络爬虫的首选语言。 Go语言在网络开发中的特点 简洁…

Redis五大基本数据类型介绍及其使用场景

文章目录 1 String&#xff08;字符串&#xff09;应用场景 2 List&#xff08;列表&#xff09;应用场景 3 Set&#xff08;集合&#xff09;4 sorted set&#xff08;有序集合&#xff09;应用场景 5 hash&#xff08;哈希&#xff09;应用场景 Redis 是一个开源&#xff0c;…

Spring Boot集成zookeeper快速入门Demo

1.什么是zookeeper&#xff1f; Zookeeper 是一个开源的分布式协调服务&#xff0c;目前由 Apache 进行维护。Zookeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。它具有以下特性…

webAPIs第二天

事件监听 什么是事件&#xff1f; 事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮 什么是事件监听&#xff1f; 就是让程序检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函数做出响应&#xff0c;也称为 绑定事件或者…

常用的30个linux命令总结

1、常用30个命令总结 2、具体参数用法参考网站&#xff1a; Linux命令大全(手册) – 真正好用的Linux命令在线查询网站

Linux提权--第三方软件MYSQL数据库提权(WEB+本地)

免责声明:本文仅做技术交流与学习,非法搞事后果自负... 目录 靶场镜像: 过程: 手工: 下载mysql udf poc 进行编译. 进入数据库进行UDF导出 下载(上传) 创建do_system函数调用 探针(./LinEnum.sh),查找suid权限. 配合使用find调用执行 工具: 过程: 外连不上? 隧道出…

【网络安全入门】你必须要有的学习工具(附安装包)零基础入门到进阶,看这一篇就够了!

工欲善其事必先利其器 在新入门网络安全的小伙伴而言。这些工具你必须要有所了解。本文我们简单说说这些网络安全工具吧&#xff01; Web安全类 Web类工具主要是通过各种扫描工具&#xff0c;发现web站点存在的各种漏洞如sql注入、xss等。从而获取系统权限&#xff0c;常用的…

Node.js版本管理工具nvm安装

1.下载nvm https://github.com/coreybutler/nvm-windows/releaseshttps://github.com/coreybutler/nvm-windows/releases 2.安装nvm 双击打开下载好的压缩包解压出的文件 目录中不要有中文 这个是配置切换node版本后的存储位置 然后一路下一步就行了 3.安装并使用node 安装…

vue uniapp 小程序 判断日期是今天(显示时分秒)、昨天、本周的周几、超出本周显示年月日

效果图&#xff1a; util.js /*** 转换时间*/ const messageFormat (datetime) >{ let result "";let currentTime new Date();if(isToday(datetime)){result datetime.substring(11,16);}else if(isYesterday(datetime)){result "昨天";}else if(…

代码随想录阅读笔记-动态规划【爬楼梯】

题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a;给定 n 是一个正整数。 示例 1&#xff1a; 输入&#xff1a; 2输出&#xff1a; 2解释&#xff1a; 有两种方法可以爬到楼…

2024年小程序视频如何下载到手机

在2024年的数字时代&#xff0c;小程序已成为我们生活中不可或缺的一部分&#xff0c;它们如同星辰般点缀在我们的日常之中&#xff0c;为我们带来便捷与乐趣。然而&#xff0c;你是否曾因网络的不稳定而错失了那些精彩绝伦的小程序视频&#xff1f;是否曾在离线的时刻&#xf…

面试高频知识点:Java互联网大厂高频面试题(持续收录)

文章目录 前言一、Java基础题1、Java语言的三大特性2、JDK 和 JRE 有什么区别3、Java基本数据类型及其封装类4、说明一下public static void main(String args[])这段声明里关键字的作用5、java的数据结构有哪些&#xff1f;6、抽象类和接口的区别?7、 与 equals 的区别8、Str…

导航app为什么知道还有几秒变绿灯?

在使用地图导航app行驶至信号灯的交叉路口时&#xff0c;这些应用程序会贴心地告知用户距信号灯变化还有多少秒&#xff0c;无论是即将转为绿灯还是红灯。这一智能化提示不仅使得驾驶员能适时做好起步或刹车的准备&#xff0c;有效缓解了因等待时间不确定而产生的焦虑情绪&…

邮箱API发送邮件调试的方法?有哪些限制?

邮箱API发送邮件调试的好处&#xff1f;如何正确调试邮箱API&#xff1f; 使用邮箱API发送邮件是一个常见的需求。然而&#xff0c;当遇到发送失败、内容错误或格式问题时&#xff0c;如何进行有效的调试就显得尤为重要。本文将为您介绍一些邮箱API发送邮件调试的方法&#xf…

【联通官网及APP注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

【2024】前端,该卷什么呢?

✅顺便推个机会&#xff0c;技术大厂&#xff0c;部门捞人&#xff0c;前后端可投。 2024ChatGPT 的炸裂式发展&#xff0c;很多大佬都亲自入场整活儿&#xff0c;你不得不说&#xff0c;人工智能时代的未来已来&#xff0c;大势所趋&#xff0c;不可阻挡。随着生成式AI的迅猛发…

红队攻防|拿下服务器root权限

0x00前言 分享一个简单的项目&#xff0c;小有坎坷但仍旧几乎畅通无阻的最终拿下root权限。 先说重要的事情&#xff1a; 如有漏码少码导致能定位目标请各位师傅手下留情&#xff0c;后台留言提醒必有红包重谢&#xff01; 0x01信息收集 过程略&#xff0c;收集到目标的主站…

[QT] 断点调试

目录 一 设置断点 二 调试窗口信息 2.1 默认窗口 2.2 详细窗口属性 三 调试方法和技巧 一 设置断点 在QtCreator中我们有两种方式添加断点。 用鼠标直接点击代码编辑窗口中的某一行按下F9添加/取消断点(操作的是当前鼠标光标所在的代码行) 二 调试窗口信息 2.1 默认窗…