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

Java EE初阶启程记06---synchronized关键字

 🔥个人主页:寻星探路

🎬作者简介:Java研发方向学习者

📖个人专栏: 、《

⭐️人生格言:没有人生来就会编程,但我生来倔强!!!



目录

一、synchronized关键字---监视器锁 monitor lock

1、synchronized的特性

1.1互斥锁

1.2可重入锁

2、synchronized 使用示例

2.1修饰代码块:明确指定锁哪个对象

2.2直接修饰普通方法:锁的SynchronizedDemo对象

2.3修饰静态方法:锁的SynchronizedDemo类的对象

3、Java标准库中的线程安全类


一、synchronized关键字---监视器锁 monitor lock

1、synchronized的特性

1.1互斥锁

        synchronized会起到互斥效果,某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象synchronized就会阻塞等待

        进入synchronized修饰的代码块,相当于加锁

        退出synchronized修饰的代码块,相当于解锁

        synchronized用的锁是存在Java对象头里的

synchronized 几个要点:
1)进入{就是加锁,进入}就是解锁
2)加锁 操作是会防止其他线程“插队”不影响本线程调度出 cpu(和临界区做区分)
3)锁对象,两个线程针对同一个对象加锁,才会有锁竞争,不同对象,则不会有~~

        可以粗略理解成,每个对象在内存中存储的时候,都存有一块内存表示当前的“锁定”状态(类似于厕所的“有人/无人”)

        如果当前是“无人”状态,那么就可以使用,使用时需要设为“有人”状态

        如果当前是“有人”状态,那么其他人无法使用,只能排队

(以搞对象为例子(当笑话就好,纯属虚构,只为了帮助理解!!!))

理解“阻塞等待”:

        针对每一把锁,操作系统内部都维护了一个等待队列,当这个锁被某个线程占有的时候,其他线程尝试进行加锁,就加不上了,就会阻塞等待,一直等到之前的线程解锁之后,由操作系统唤醒一个新的线程,再来获取到这个锁

#注:

        上一个线程解锁之后,下一个线程并不是立即就能获取到锁,而是要靠操作系统来“唤醒”,这也就是操作系统线程调度的一部分工作

        假设有ABC三个线程,线程A先获取到锁,然后B尝试获取锁,然后C再尝试获取锁,此时B和C都在阻塞队列中排队等待,但是当A释放锁之后,虽然B比C先来的,但是B不一定就能获取到锁,而是和C重新竞争,并不遵守先来后到的规则

        synchronized的底层是使用操作系统的mutexlock实现的

1.2可重入锁

        synchronized同步块对同一条线程来说是可重入的,不会出现自己把自己锁死的问题。

理解"把自己锁死"

一个线程没有释放锁,然后又尝试再次加锁.

// 第一次加锁,加锁成功

lock();

// 第⼆次加锁,锁已经被占用,阻塞等待.

lock();

        按照之前对于锁的设定,第⼆次加锁的时候,就会阻塞等待。直到第一次的锁被释放,才能获取到第⼆个锁,但是释放第一个锁也是由该线程来完成,结果这个线程已经躺平了,啥都不想干了,也就无法进行解锁操作,这时候就会死锁

        这样的锁称为不可重入锁

        Java 中的synchronized是可重入锁,因此没有上面的问题

 for (int i = 0; i < 50000; i++) {synchronized (locker) {synchronized (locker) {count++;}}}

在可重⼊锁的内部,包含了"线程持有者"和"计数器"两个信息:

        如果某个线程加锁的时候,发现锁已经被人占用,但是恰好占用的正是自己,那么仍然可以继续获取到锁,并让计数器自增

        解锁的时候计数器递减为0的时候,才真正释放锁(才能被别的线程获取到)

2、synchronized 使用示例

        synchronized 本质上要修改指定对象的“对象头”,从使用角度来看,synchronized也势必要搭配一个具体的对象来使用

2.1修饰代码块:明确指定锁哪个对象

锁任意对象

 public class SynchronizedDemo {private Object locker = new Object();public void method() {synchronized (locker) {}}}

锁当前对象

 public class SynchronizedDemo {public void method() {synchronized (this) {}}}

2.2直接修饰普通方法:锁的SynchronizedDemo对象

 public class SynchronizedDemo {public synchronized void methond() {}}

2.3修饰静态方法:锁的SynchronizedDemo类的对象

 public class SynchronizedDemo {public synchronized static void method() {}}

        我们重点要理解,synchronized锁的是什么,两个线程竞争同一把锁,才会产生阻塞等待

两个线程分别尝试获取两把不同的锁,不会产生竞争

3、Java标准库中的线程安全类

        Java 标准库中很多都是线程不安全的,这些类可能会涉及到多线程修改共享数据,又没有任何加锁措施

        ArrayList

        LinkedList

        HashMap

        TreeMap

        HashSet

        TreeSet

        StringBuilder

但是还有一些是线程安全的,使用了一些锁机制来控制

        Vector(不推荐使用)

        HashTable(不推荐使用)

        ConcurrentHashMap

        StringBuffer

StringBuffer 的核心方法都带有 synchronized

还有的虽然没有加锁,但是不涉及“修改”,仍然是线程安全的

        String

http://www.dtcms.com/a/442500.html

相关文章:

  • QT(c++)开发自学笔记:1.串口
  • 最小外接矩形2显示四条边缘
  • 什么是网站建设与维护潘嘉严个人网站
  • 天津做网站哪家好如何申请域名后缀
  • MCP(trae)+ wireshark-提高干活效率
  • 机器视觉3D检测中,.ply(Polygon File Format) 3D点云格式
  • 如何网站优化排名做兼职比较正规的网站
  • 兰亭妙微高端网站设计案例:品牌官网如何做到美学与转化并重
  • 网站主机提供商:选择与您业务相匹配的托管服务
  • Linux学习笔记--insmod 命令
  • 做树状图的网站html全屏网站
  • 网站页面设计师如何编辑网站模板
  • 网站服务器网络企业网站设计方案
  • 数仓一些问题
  • 君正T32开发笔记之AOV实例介绍
  • 包含HPA配置与资源限制示例
  • 做影视网站用主机还是用服务器合肥网络优化公司有几家
  • 网站开发属于哪个部门贵阳网站建设电话
  • fiddler详解
  • 系统版本管理规范:从分支策略到发布流程
  • 【LLM-RL】GRPO->DAPO->GSPO训练区别
  • 建设中心小学网站上海16个区排名
  • Linux下查看和关闭进程的方法
  • 【ROS2学习笔记】动作
  • 李宏毅machine learning 2021学习笔记——Vit
  • 第三十一篇|AI 驱动的教育数据建模:以冈山外语学院为样本的结构化分析
  • 深圳网站的优化公司哪家好wordpress上传代码
  • 架构学习之旅-架构的由来
  • 洛阳市建设工程评标专家网站网站开发长沙
  • 专业的数字化转型培训方案哪家好