Java~今日学习各种锁策略(乐观锁 悲观锁 读写锁等等)、CAS机制和synchronize的原理及其优化机制(锁消除 偏向锁 自旋锁 膨胀锁 锁粗化)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 挂起等待锁 VS 自旋锁

  • 公平锁 VS 非公平锁

  • 可重入锁

  • 死锁

  • CAS

    • CAS的使用
  • CAS的缺陷 ABA问题

  • synchronize的原理

  • 以synchronize为例学习锁优化

    • 锁消除
  • 偏向锁

  • 自旋锁

  • 锁膨胀

  • 锁粗化

锁策略

乐观锁 VS 悲观锁
  • 乐观锁:乐观锁假设认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式对数据是否产生并发冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。

  • 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

悲观锁的问题:总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。

乐观锁的问题:并不总是能处理所有问题,所以会引入一定的系统复杂度。

读写锁
  • 把加锁操作分成了俩种 一是读锁二是写锁 也就是说在读和读之间是没有互斥的 但是在读写和写写之间就会存在互斥

  • 如果一个场景是一写多度 那么使用这个效率就会很高

重量级锁 VS 轻量级锁
  • 首先我们要知道加锁有一个很重要的特性就是保证原子性 原子性的功能其实来源于硬件(硬件提供了相关的原子操作的指令, 操作系统把这些指令统一封装成一个原子操作的接口, 应用程序才能使用这样的操作)

  • 所以在加锁过程中 如果整个加锁逻辑都是依赖于操作系统内核 那此时就是重量级锁(代码在内核中的开销会很大) 如果大多数操作都是用户自己完成的 少数由操作系统内核完成 这种就是轻量级锁

挂起等待锁 VS 自旋锁
  • 挂起等待锁表示当前获取锁失败后, 对应的线程就要在内核中挂起等待 (放弃CPU进入等待队列) 需要在锁对象释放之后由操作系统唤醒 (通常都是重量级锁)

  • 自旋锁表示当前获取锁失败后 不是立刻放弃CPU 而是快速频繁的再次访问锁的持有状态, 一旦锁对象被释放就能立刻获取到锁(通常都是轻量级锁)

自旋锁的效率更高, 但是会浪费一些CPU资源 (自旋相当于CPU在那空转)

公平锁 VS 非公平锁
  • 这种情况就是如果已经有多个线程在等待一把锁的释放 当释放之后, 恰好又来了一个新的线程也要获取锁

  • 公平锁: 保证之前先来的线程优先获取锁

  • 非公平锁: 新来的线程直接获取到锁, 之前的线程还得接着等待

实现公平锁就需要付出一些额外的代价 所以公平锁的效率是略低于非公平锁的

可重入锁
  • 一个线程针对同一把锁连续加锁俩次, 不会死锁, 这种就是可重入锁

可重入锁这就像是大门的三保险锁一样 我锁一层再锁一层 这种并不会造成我们死锁住自己 因为当我们想出去的时候又可以一层一层的开锁

死锁
  • 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

  • 我们常说的死锁有三个经典场景

  1. 一个线程一把锁 连续加锁俩次才 (保证使用的不是可重入锁)
  1. 俩个线程, 俩把锁, 相互获取对方的锁
  1. n个线程, n把锁, 哲学家就餐问题
  • 死锁产生的四个必要条件:(较为理论简单了解)

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

CAS

  • CAS的全称是 compare and swap(字面意思就是比较交换) 他是基于硬件提供的一种基础指令, 也是基于这样的指令, 就可以实现一些特殊的功能(实现锁)

  • 针对不同的操作系统,JVM 用到了不同的 CAS 实现原理

  • 简而言之,是因为硬件予以了支持,软件层面才能做到。

我们假设内存中的原数据val,旧的预期值new,需要修改的新值tmp。

  1. 比较 new 与 val 是否相等。(比较)
  1. 如果比较相等,将 tmp 写入 val。(交换)
  1. 返回操作是否成功。
  • 可见当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。可见 CAS 其实是一个乐观锁。
CAS的使用

在这里插入图片描述

上图所示就是使用的CAS封装了一些原子类如下面代码示例第一个使用CSA的锁第二个不使用 显然结果第一个是线程安全的第二个线程是不安全的

import java.util.concurrent.atomic.AtomicInteger;

/**

  • Created with IntelliJ IDEA.

  • Description: If you don’t work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-04

  • Time: 20:40

*/

public class Demo2 {

public static void main(String[] args) throws InterruptedException {

AtomicInteger atomicInteger = new AtomicInteger();

Thread thread = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

atomicInteger.addAndGet(1);

}

}

};

Thread thread1 = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

atomicInteger.addAndGet(1);

}

}

};

thread.start();

thread1.start();

thread.join();

thread1.join();

System.out.println(atomicInteger.get());

}

}

/**

  • Created with IntelliJ IDEA.

  • Description: If you don’t work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-04

  • Time: 20:53

*/

public class Demo3 {

private static int count = 0;

public static void main(String[] args) throws InterruptedException {

Thread thread = new Thread() {

@Override

总结

上述知识点,囊括了目前互联网企业的主流应用技术以及能让你成为“香饽饽”的高级架构知识,每个笔记里面几乎都带有实战内容。

很多人担心学了容易忘,这里教你一个方法,那就是重复学习。

打个比方,假如你正在学习 spring 注解,突然发现了一个注解@Aspect,不知道干什么用的,你可能会去查看源码或者通过博客学习,花了半小时终于弄懂了,下次又看到@Aspect 了,你有点郁闷了,上次好像在哪哪哪学习,你快速打开网页花了五分钟又学会了。

从半小时和五分钟的对比中可以发现多学一次就离真正掌握知识又近了一步。

人的本性就是容易遗忘,只有不断加深印象、重复学习才能真正掌握,所以很多书我都是推荐大家多看几遍。哪有那么多天才,他只是比你多看了几遍书。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
3410015106)]

人的本性就是容易遗忘,只有不断加深印象、重复学习才能真正掌握,所以很多书我都是推荐大家多看几遍。哪有那么多天才,他只是比你多看了几遍书。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-whdso9re-1713410015107)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值