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

JUC 并发编程_锁

synchronized

关键字

同步锁

修饰代码块和方法

修饰方法不能被继承

修饰静态方法 相当于锁住了整个类

修饰代码块

同一个时间只能有一个人操作这个代码块

售票

出现抢票

没抢到一直抢

一直抢到为止

只有一个线程能通过

不存在公平

排他锁

隐式可重入锁

同一个线程对对象反复加锁

必须是同一个线程

隐式 : 看不到第二把锁 也控制不住

对对象反复加锁

成功可重入

失败 不可重复

对象头

  • 对象

    • 对象头
    • 实例数据
    • 对其填充
  • 对象头

    • markword : 存储对象的哈希码 GC分代的年纪 锁信息
    • 一个类的元数据地址
    • 数组长度 有数组就有着玩意 没有那就没有 专门存数组的
  • markword 32

    • HashCode 25 GC4 锁信息3
      • 锁状态
        • 无锁 一个对象没有竞争 效率最高
        • 偏向锁 比如被 synchronized修饰 没有竞争
          • 把名字写到线程ID中 偏向锁从0变1
          • 如果下次不用的话只是把线程ID清除
        • 偏向锁 有竞争
          • 双方都争抢着把自己的名字写到线程ID中去
          • 但是一方是带着synchronized来的所以另一方一直失败
          • 一直到清掉的一瞬间 另一方抢到锁
          • 抢到了锁 加ID 不加偏向锁 因为他知道有人抢 不保险
        • 升级轻量级 锁标识位变成00
          • 操作完清ID 后面没有人操作 时间到 jvm直接清锁
        • 重量级 锁标识位11 竞争激烈
          • 一个对象无锁 发现synchronized 加偏向锁
          • 然后一堆人操作这个对象
          • 其中一个人操作到了 加轻量级 写ID
          • 剩下一堆人中的一个人操作到了这个对象直接加重量级锁
    • 1.8以前直接上重量级

锁消除

编译时 如果对象每次都是自己new 出来的 没有竞争 那么运行时程序会把锁消除

锁粗化

编译时 加锁 加一万次 和一次没区别的化 那么编译器会直接优化成一次

自旋锁和自适应自旋锁

  • 自旋
    • 枪锁的时候会写自己的ID
    • 写完ID改锁标识位
    • 这个改ID的过程就是叫做自旋
  • 死循环写ID
    • 里面枪锁的过程有个while(true){}循环
    • 抢到了 跳出break
    • 循环执行几次 就是自旋了几次
  • 区别
    • 告诉下一个枪锁的 别的线程循环抢到锁的次数作为参照值
    • 然后大于等于上一次的次数 参照值 超过就不强了

Lock

public interface Lock {
    void lock();//加锁 成功失败 结果不知道 就试一次

    void lockInterruptibly() throws java.lang.InterruptedException; //中断锁

    boolean tryLock();//尝试加锁 知道结果

    boolean tryLock(long l, java.util.concurrent.TimeUnit timeUnit) throws java.lang.InterruptedException;//重载方法没有 参数 给时间段 直到为true或者时间到下一步

    void unlock();//释放锁

    java.util.concurrent.locks.Condition newCondition();//钥匙
}

加锁一次 成功就成功 不成功就阻塞

如果Lock不释放锁就会死锁

集合线程安全

ArrayList 多个线程同时堆集合进行修改

如果有同步操作 就会出现并发修改异常

如何解决List类型的线程安全问题?

用Vector

他基于AbstactList是实现List

add方法被synchronized同步修饰 所以没有并发修改异常

用Collections

里面也提供了synchronized方法 保证list同步线程安全

CopyOnWriteArrayList

和ArratList一样是一个可变数组

线程安全

往容器中添加数据的时候 不直接添加 先复制容器 然后在新的容器里面添加然后再将原容器指向新容器

会产生数据不一致 会产生脏数据

相关文章:

  • java基于springboot+vue的高校大学生社团活动管理系统
  • 框架之SpringBoot基础(二)
  • 【小程序】中WXS的语法详解
  • Spring Cloud Gateway - GatewayFilter路由过滤器
  • 猿创征文|大数据之Kafka简介+基操
  • Shiro授权--注解式开发
  • CREO:CREO软件之零件【编辑】之修饰、用户定义特征的简介及其使用方法(图文教程)之详细攻略
  • Java并发 | 12.[方法] interrupt( )打断
  • SpringBoot 事务开发代码及注意事项
  • onnx: step = 1 is currently not supported
  • webpack原理篇(六十五):实战开发一个压缩构建资源为zip包的插件
  • 数学建模学习(97):花授粉算法(FPA)寻优
  • 鲈鱼的面试题库+答案
  • CREO:CREO软件之零件【工具(调查/模型意图/实用工具)】、【视图(可见性/方向/模型显示/显示/窗口)】的简介及其使用方法(图文教程)之详细攻略
  • 【单细胞高级绘图】09.细胞通讯_两组比较_连线图
  • [译] 怎样写一个基础的编译器
  • Fundebug计费标准解释:事件数是如何定义的?
  • IndexedDB
  • JavaScript中的对象个人分享
  • Java超时控制的实现
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Median of Two Sorted Arrays
  • Netty源码解析1-Buffer
  • python docx文档转html页面
  • Redis 中的布隆过滤器
  • vuex 学习笔记 01
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • Vue全家桶实现一个Web App
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 开源地图数据可视化库——mapnik
  • 目录与文件属性:编写ls
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 深入浏览器事件循环的本质
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • ​​​​​​​​​​​​​​Γ函数
  • #HarmonyOS:基础语法
  • (02)Hive SQL编译成MapReduce任务的过程
  • (33)STM32——485实验笔记
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (C语言)字符分类函数
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (四)鸿鹄云架构一服务注册中心
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转载)hibernate缓存
  • .gitignore文件—git忽略文件
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .net 微服务 服务保护 自动重试 Polly
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • @JsonFormat与@DateTimeFormat注解的使用
  • @vue/cli 3.x+引入jQuery