学习笔记9——JUC三种量级的锁机制

学习笔记系列开头惯例发布一些寻亲消息

链接:https://baobeihuijia.com/bbhj/contents/3/197325.html
在这里插入图片描述

  • 多线程访问共享资源冲突

    • 临界区:一段代码块存在对共享资源的多线程读写操作,称这段代码块为临界区

    • 竞态条件:多个线程在临界区内执行,由于代码的执行序列不同导致结果无法预测,称发生了竞态条件

  • 一些线程安全的例子(什么时候加锁什么时候不加):

    • 局部变量是线程安全的(每个线程创建的栈内部独立拥有)
      在这里插入图片描述

    • 局部变量引用的对象:如果用的对象的公共变量,需要加锁,因为对象在堆内
      在这里插入图片描述

    • 局部变量引用的对象:如果用的是对象方法内的局部变量**(虽然这种情况下每个线程在堆内单独拥有对象使用权,但是如果子类重写方法,新加了线程,那么也会出现两个线程共享局部变量的情况,所以尽量用final或者private将父类保护起来)**

    在这里插入图片描述

    • 线程安全类:

      • string:在定义string类的时候,就已经声明了final,所以不会出现子类继承string,并且修改string的读写逻辑为多线程,所以对于单独一个string来说,我们的读写是安全的,因为只有有一个线程进行读写,但是多个方法的组合之间可以插入不同的别的线程,所以不是原子或者说不是安全的。
        在这里插入图片描述
  • 在这里插入图片描述

  • 重量级锁——synchronized【父母考核:我听父母的,父母来决定我的owner,当追求者很多时,采用这种方案】

    • 加锁room,别的线程会进入block,直到本线程释放锁,才会唤醒别的block线程,在这个过程中就算时间片轮完该线程,其他线程也无法唤醒

    • 用对象锁的形式保证了临界区代码的原子性,避免多个线程一起执行同一段临界区代码,如果这个锁没有被用,那么就可以执行这段代码

    • 锁住对象和锁住类对象是不同的,并不互斥(也就是说,在执行锁住对象的时候,当这轮cpu片时间耗尽,cpu也会去执行锁住类对象的操作,类对象锁不会被阻塞)

      # 方法一
      synchronized(对象)# 方法二
      class Room {private int counter = 0;// 等价于 synchronized(this)public synchronized void increment() {counter++;}public synchronized void decrement() {counter--;}public synchronized int getCounter() {return counter;}
      }# 方法三
      class Test{// 等价于synchronized(Test.class)public synchronized static void test(){}
      }
      
    • Monitor

      • 对象头

        • 普通对象:32bit的Mark Word(25位hashcode,每个对象都有自己的哈希码,4位的GC分代,锁状态标志)+32bit的Klass Word(类型指针)
      • 数组对象:32bit mark word + 32bit klass word + 32bit的 数组长度

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • synchronized的原理:

      • 每次线程遇到synchronized(obj),会去检查obj是否指向操作系统中的一个monitor,如果没有指向那就将obj对象的mask word 修改为monitor的地址,并将锁标志位从01改为10,将该线程置为monitor的Owner
      • 在此期间如果别的线程执行遇到synchronized(obj),那么就会索引到monitor,发现已经有别的owner,进入entrylist 变为BLOCKED状态
      • 当前owner执行完成后,随机唤醒一个BLOCKED线程,最后退出该对象时将自己的markword重置为hashcode等

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 重量级锁的线程自旋优化

      • 为了避免线程阻塞,发生上下文切换,从而自旋等待解锁
      • 适合多核cpu,单核的cpu没有自旋的意义,因为没有额外的cpu可以来执行自旋(需要等你结束我才能执行,但是我还总要中途打扰你问你好了没)
      • 自旋失败:几次自旋重试后还是得不到锁就进行阻塞
  • 轻量级锁(操作系统自动创建,不需要我们显式定义)【私定终生,我来决定我的owner】

    • 加锁:线程中创建一个LOCK RECORD 00表示轻量级锁,与对象头交换mask信息(类似于一种密码机制,只有当前线程完成后,才会把密码信息还给对象,别人来访问交换时这个对象已经是加锁状态)

    • 锁重入:当前线程已经拿到锁了,但是又执行了一遍synchronized(obj),这时会新建一个LOCK RECORD 00栈帧,数据这里会存储null,说明其他栈帧已经拿到锁了

    • 解锁:如果是null,直接清除即可,不是null则需要将mask word恢复给对象

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 锁膨胀(追求者很多产生了竞争,发现决定权给到父母后,就需要与父母沟通)

      • 线程加轻量级锁失败,进入锁膨胀流程,变成重量级锁(修改原始密码为monitor地址,owner置为当前线程,后续线程进入阻塞)
      • 原来线程的轻量级锁解锁失败(因为密码匹配不对,对象的密码现在是monitor地址),需要进入重量级锁的解锁流程,即找到monitor对象,将owner置为null,并唤醒阻塞线程

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 偏向锁(只有一个线程一直重复用偏向——》有别的线程也来用该对象就会撤销变为轻量级锁——》锁之间有竞争交互就用重量级)

    • 原始:将对象的mask word与新建锁栈帧的头部信息交换(锁重入都会尝试交换信息,造成资源浪费)

    • 偏向:将对象的mask word修改为线程ID,锁重入就不会新建锁栈帧

    • 当前线程id释放后,线程id还是不会改变,该对象已经从属于该主线程

    • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • ban掉偏向锁的方法

      • 当一个可偏向的对象调用了hashcode就会ban掉偏向锁
      • 当对象已经偏向一个线程了,另一个线程也来用该对象,但是不竞争,就会变为轻量级(线程id部分变为锁记录指针),如果竞争交互就是重量级
      • 调用wait,notify也会撤销,因为wait,notify只有重量级有
    • 批量重偏向

      • 超过一定阈值数量(20)的对象都在撤销偏向锁,就会认为偏向设置的线程有误,因此会将所有的对象偏向锁改为别的线程
      • 撤销的性能消耗比较大
      • 批量执行
    • 批量撤销

      • 撤销超过阈值(40)的对象都在撤销偏向锁换轻量级(说的是所有线程的总数),偏向就要求整个类原始对象和新对象不再偏向,直接轻量级
  • JIT即时编译进行逃逸分析

  • sleep和wait的区别(状态都是timewaiting)

    • sleep是线程的方法,执行时不会放弃锁:相当于屋子内的人把门锁死,直到醒来检查一下资源是否满足

    • wait是对象A的方法,会放弃锁,需要notify叫醒:屋子内的人发现缺资源就出来在门外等着A.wait(),等到资源满足执行notify【这种方法可以通过资源的识别需要通过while条件来判断】

      • synchronized(lock){while(资源不满足){lock.wait();}// 干活
        }synchronized(lock){lock.notifyAll()
        }
        

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

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

相关文章

Linux OpenMP使用总结

当涉及到编写 Linux OpenMP 程序时,以下是体会: 了解 OpenMP 基础:在使用 OpenMP 进行并行编程之前,确保您了解并行编程的基本概念和 OpenMP 的工作原理。您可以参考 OpenMP 的官方文档或其他相关资源来获取更多信息。配置 OpenM…

#HarmonyOS:@Styles装饰器:定义组件重用样式

Styles可以定义在组件内或全局,在全局定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。 组件内Styles的优先级高于全局Styles。 框架优先找当前组件内的Styles,如果找不到,则会全局查找。 // …

GO设计模式——3、抽象工厂模式(创建型)

目录 抽象工厂模式(Abstract Factory Pattern) 抽象工厂模式的核心角色 优缺点 代码实现 抽象工厂模式(Abstract Factory Pattern) 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他…

单词倒排

对字符串中的所有单词进行倒排。 说明: 1、构成单词的字符只有26个大写或小写英文字母; 2、非构成单词的字符均视为单词间隔符; 3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排…

yolo目标检测+目标跟踪+车辆计数+车辆分割+车道线变更检测+速度估计

这个项目使用YOLO进行车辆检测,使用SORT(简单在线实时跟踪器)进行车辆跟踪。该项目实现了以下任务: 车辆计数车道分割车道变更检测速度估计将所有这些详细信息转储到CSV文件中 车辆计数是指在道路上安装相应设备,通过…

windows下 Tomcat启动黑框隐藏

进入到 tomcat/bin 目录下,找到此文件 setclasspath.bat ,右键文本打开 找到此属性 : set _RUNJAVA"%JRE_HOME%\bin\java.exe"修改成以下属性,保存文件,重启启动tomcat会发现黑框不默认弹出了: …

使用hutool工具生成非对称加密公私密钥以及使用案例

1.导入hutool依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency>2.直接复制代码 package com.common.utils;import cn.hutool.core.codec.Base64; i…

仅需30秒完美复刻任何人的声音 - 最强AI音频11Labs

我的用词一直都挺克制的&#xff0c;基本不会用到“最强”这个字眼。 但是这一次的这个AI应用&#xff0c;是我认为在TTS&#xff08;文字转音频&#xff09;这个领域&#xff0c;当之无愧的“最强”。 ElevenLabs&#xff0c;简称11Labs。 仅需30秒到5分钟左右的极少的数据集…

机器学习-分类问题

前言 《机器学习-回归问题》知道了回归问题的处理方式,分类问题才是机器学习的重点.从数据角度讲,回归问题可以转换为分类问题的微分 逻辑回归 逻辑回归&#xff08;Logistics Regression&#xff09;,逻辑回归虽然带有回归字样&#xff0c;但是逻辑回归属于分类算法。但只可…

极大提升GPT-4等模型推理效率,微软、清华开源全新框架

随着用户需求的增多&#xff0c;GPT-4、Claude等模型在文本生成、理解、总结等方面的能力越来越优秀。但推理的效率并不高&#xff0c;因为&#xff0c;多数主流模型采用的是“顺序生成词”方法&#xff0c;会导致GPU利用率很低并带来高延迟。 为了解决这一难题&#xff0c;清…

美国Linux服务器的iptables防火墙介绍

美国Linux服务器防火墙一般分为硬件防火墙和软件防火墙&#xff0c;但不论是硬件防火墙还是软件防火墙&#xff0c;都需要通过使用硬件作为联机的介质&#xff0c;也需要使用软件来设定美国Linux服务器安全政策&#xff0c;因此可以从使用的硬件与操作系统来加以区分。硬件防火…

oracle怎么推进scn?

很多时候&#xff0c;数据库有故障打不开&#xff0c;需要用到推进scn的技术&#xff0c;这里介绍下12c及以上版本的oracle怎么推进数据库的scn。 经测试发现&#xff0c;数据库mount和open状态下都可以通过此方法推进SCN。 Session1&#xff1a; 查询当前SCN SQL> select c…

基于jsp+servlet的图书管理系统

基于jspservlet的图书管理系统演示地址为 图书馆后台管理系统 用户名:mr ,密码:123 图书馆管理系统主要的目的是实现图书馆的信息化管理。图书馆的主要业务就是新书的借阅和归还&#xff0c; 因此系统最核心的功能便是实现图书的借阅和归还。此外&#xff0c;还需要提供图书…

Stable Diffusion XL on diffusers

Stable Diffusion XL on diffusers 翻译自&#xff1a;https://huggingface.co/docs/diffusers/using-diffusers/sdxl v0.24.0 非逐字翻译 Stable Diffusion XL (SDXL) 是一个强大的图像生成模型&#xff0c;其在上一代 Stable Diffusion 的基础上主要做了如下优化&#xff1a;…

生产上线需要注意的安全漏洞

一、关闭swagger 1、关闭swagger v3 # 需同时设置auto-startupfalse&#xff0c;否则/v3/api-docs等接口仍能继续访问 springfox:documentation:enabled: falseauto-startup: falseswagger-ui:enabled: false 2、关闭swagger v2 # 只要不是true就不启用 swagger:enable: fa…

深度解读:淘客返利机器人无限制与免费版的差异

深度解读:淘客返利机器人无限制与免费版的差异 在数字时代&#xff0c;人工智能和大数据技术的飞速发展正在改变我们的生活方式&#xff0c;尤其在购物领域&#xff0c;各种优惠工具如雨后春笋般涌现。其中&#xff0c;淘客返利机器人和微赚淘客系统以其独特的优势&#xff0c…

Python核心编程之序列下篇

目录 十二、列表 如何创建列表类型数据并给它赋值 如何访问列表中的值

代立冬:基于Apache Doris+SeaTunnel 实现多源实时数据仓库解决方案探索实践

大家好&#xff0c;我是白鲸开源的联合创始人代立冬&#xff0c;同时担任 Apache DolphinScheduler 的 PMC chair 和 SeaTunnel 的 PMC。作为 Apache Foundation 的成员和孵化器导师&#xff0c;我积极参与推动多个开源项目的发展&#xff0c;帮助它们通过孵化器成长为 Apache …

如何访问内部网络做内网穿透

项目&#xff1a;https://github.com/ehang-io/nps 有个公网服务器&#xff0c;搭建服务端。 然后客户端使用&#xff1a; -server是服务端的访问方式。-vkey是秘钥。 ./npc -server192.227.19.12:8024 -vkeyoies8gq3wml -typetcp然后在服务端配置TCP隧道即可。

某度旋转验证码v2 逆向分析

v2主要依据是核心 JS 文件mkd_v2.js 版本&#xff0c;如下图所示&#xff1a; 第一次 https://passport.baidu.com/cap/init 接口&#xff0c;请求的 ak 是固定值&#xff0c;当然不同场景不同网站是不一样的&#xff0c;_ 时间戳&#xff0c;ver1&#xff0c;返回值 as、tk 都…