自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(141)
  • 资源 (1)
  • 收藏
  • 关注

原创 十二:深入理解 Exchanger —— 交换器

Exchanger:交换器。用于在线程之间交换数据,但是比较受限,因为只能两个线程之间交换数据。

2024-04-20 15:25:11 188

原创 十一:深入理解 Semaphore —— 信号量

不管线程 D 有没有进入阻塞队列【如果没有进入,那么此时,线程 D 和 线程 C 竞争许可证】,这里假设是线程 C 获取许可证成功,没有多余的许可证(propagate = 0),那么线程 D 就会进入到同步队列【此时,有可能阻塞(线程C.waitStatus = -1),也有可能没阻塞(线程C.waitStatus = 0)】:将当前线程封装为【共享模式】节点入同步队列,再自旋,如果当前节点前驱是 head 节点,再次获取许可证,如果返回结果 >= 0,则表示获取许可证成功,则调用。

2024-04-20 11:47:16 717

原创 十:深入理解 CyclicBarrier—— 栅栏锁

让一组线程到达某个屏障,被阻塞,一直到组内的最后一个线程到达,然后屏障开放,接着,所有的线程继续运行是通过独占锁实现的,底层包含了 “ReentrantLock 对象 lock” 和 “Condition 对象 trip”,通过条件队列 trip 来对线程进行阻塞的,并且其内部维护了两个 int 型的变量 parties 和 count。

2024-04-18 17:05:22 412

原创 九:深入理解 CountDownLatch —— 闭锁/倒计时锁

通过构造方法初始化:设置 AQS 中的 state 的值调用方法:调用 AQS 的释放同步状态的方法,每调用一次,state 就自减 1,直至为 0调用await()方法:如果 state 不为 0,则阻塞线程并入队列。当 state 为 0 后,唤醒其它所有阻塞的线程。

2024-04-18 14:24:29 1011

原创 八:深入理解 Condition —— 线程通信(等待/通知)

当一个持有锁的线程调用将当前线程加入到条件等待队列中,状态为【CONDITION】彻底释放锁,并唤醒同步队列中阻塞的一个线程判断自己是否在同步等待队列中,如果不在,将自己阻塞起来如果被signal()方法唤醒了,则去竞争同步锁当一个持有锁的线程调用删除条件等待节点的头节点将头节点添加到同步等待队列的 tail 之后,如果添加成功,则退出循环;否则,如果条件等待队列中还有节点,则后移,循环步骤 1、2修改头结点的状态【CONDITION => 0】

2024-04-16 16:37:01 991

原创 七:深入理解 ReentrantReadWriteLock —— 读写锁

`ReentrantReadWriteLock`:读写锁。它表示两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁。适用于**读多写少**的场景(如果用独占锁,效率及其低下),提高并发性能,但也需要更多的内存和处理器时间来维护状态信息

2024-04-15 14:22:52 642

原创 六:深入理解 ReentrantLock —— 可重入锁

在文章中,我们介绍了 AQS 的基本原理。是我们比较常用的一种锁,也是基于 AQS 实现的。所以,接下来我们就来分析一下锁的实现。

2024-04-13 11:46:03 564

原创 五:深入理解 AbstractQueuedSynchronizer

抽象队列同步器,定义了一套多线程访问共享资源的同步器框架(同步:线程之间的通信、协作),许多同步类实现都依赖于它,如:Lock 包中的各种锁()、concurrent包中的各种同步器(如Semaphore),还有阻塞队列和线程池的实现都有使用到 AQS实现原理:在多线程访问共享资源时,若标识的共享资源【state】空闲,则将当前获取到共享资源的线程设置为有效工作线程,共享资源设置为锁定状态(独占模式下),其他线程没有获取到资源的线程进入阻塞队列【CLH】,等待当前线程释放资源后,继续尝试获取。

2024-04-12 11:54:10 752 1

原创 四:深入理解 volatile 关键字

volatile 变量,保证新值能立即同步回主内存,以及每次使用前立即从主内存刷新,所以我们说volatile保证了多线程操作变量的可见性

2024-04-11 15:57:04 555

原创 三:深入理解 synchronized 关键字

count = 0;_waiters = 0,//等待线程数//重入次数//持有锁的线程(逻辑上,实际上除了THREAD,还可能是Lock Record)//线程wait之后会进入该列表//等待获取锁的线程列表,和_EntryList配合使用//等待获取锁的线程列表,和_cxq配合使用//当前持有者是否为THREAD类型,如果是轻量级锁膨胀而来,还没有enter的话,//_owner存储的可能会是Lock Record当多个线程同时访问一段同步代码时,首先会进入。

2024-04-09 20:42:20 692

原创 二:深入理解 JAVA 内存模型 JMM

上述问题是因硬件的不断升级导致的。那么,有没有什么机制可以很好的解决上面的这些问题呢?——内存模型为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性【与处理器/缓存/并发/编译器有关】。它解决了 CPU 多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性和有序性。限制处理器优化和使用内存屏障同一套内存模型规范,不同语言在实现上可能会有些差别。

2024-04-09 12:02:42 710

原创 【MYSQL】MYSQL 的学习教程(十三)之 MySQL的加锁规则

MySQL 分成了 Server 层和存储引擎两部分,每当执行一个查询时,Server 层负责生成执行计划,然后交给存储引擎去执行。弄懂了上面两个认识,会对后续大家理解有很大帮助。例如:对于进行分析的时候,为什么会出现说第一次加锁是精确查询?它明明是范围查询呀!这是因为第一次是要寻找到 id = 5 的记录,对于 Innodb 来说,它就是精确查找,不是范围查找。随后找到 id = 5 的记录之后,就要找 id > 5 的记录了,此时就变成了范围查找了。

2024-01-09 15:16:40 1231

原创 【MYSQL】MYSQL 的学习教程(十二)之 MySQL 啥时候用记录锁,啥时候用间隙锁

在「读未提交」和「读已提交」隔离级别下,都只会使用;而对于「可重复读」隔离级别来说,会使用那么 MySQL 啥时候会用记录锁,啥时候会用间隙锁,啥时候又会用 Next-Key 锁呢?

2024-01-08 16:48:12 1091

原创 【MYSQL】MYSQL 的学习教程(十一)之 MySQL 不同隔离级别,都使用了哪些锁

在「读未提交」隔离级别下,读写操作可以同时进行,但写写操作无法同时进行。与此同时,该隔离级别下只会使用行级别的记录锁,并不会用间隙锁在「读已提交」隔离级别下,只会使用行级别的记录锁,并不会用间隙锁。在「可重复读」隔离级别下,使用了记录锁、间隙锁、Next-Key 锁三种类型的锁可重复读存在幻读的问题,但实际上在 MySQL 中,因为其使用了间隙锁,所以在「可重复读」隔离级别下,可用加锁解决幻读问题。因此,MySQL 将「可重复读」作为了其默认的隔离级别。

2024-01-06 11:20:03 1138

原创 【MYSQL】MYSQL 的学习教程(十)之 InnoDB 锁

表锁:当存储引擎不支持行级锁时,使用表锁;SQL 语句没有匹配到索引时,使用表锁元数据锁:对表做增删改查时,会加上 MDL 读锁。对表结构做变更时,会加上 MDL 写锁意向锁:对表中的行记录加锁时,会用到意向锁行级锁:增删改查匹配到索引时,会使用行级锁。

2023-12-28 16:24:21 1344

原创 【MYSQL】MYSQL 的学习教程(九)之 23 个 SQL 优化小技巧

这篇文章从 15 个方面,分享了 sql 优化的一些小技巧,希望对你有所帮助。

2023-12-26 13:57:00 881

原创 【MYSQL】MYSQL 的学习教程(八)之 12 种慢 SQL 查询原因

当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为**“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”**。一般有更新 SQL 才可能会导致脏页。

2023-12-25 18:04:29 1638 2

原创 【MYSQL】MYSQL 的学习教程(七)之 慢 SQL 优化思路

开启 profiling 参数后,后续执行的 SQL 语句都会记录其资源开销,包括 IO,上下文切换,CPU,内存等等,我们可以根据这些开销进一步分析当前慢 SQL 的瓶颈再进一步进行优化。profile 只能查看到 SQL 的执行耗时,但是无法看到 SQL 真正执行的过程信息,即不知道 MySQL 优化器是如何选择执行计划。定义,默认是 15。如果我们需要看单独某条 SQL 的分析,可以 show profile 查看最近一条 SQL 的分析,也可以使用。表示查询时能够使用到的索引(显示的是索引名称),

2023-12-25 18:03:32 1068

原创 【MYSQL】MYSQL 的学习教程(六)之 SQL 语句执行流程

Buffer Pool 是 MySQL 的一个非常重要的组件,因为针对数据库的增删改操作都是在 Buffer Pool 中完成的Undo log 记录的是数据操作前的样子redo log 记录的是数据被操作后的样子(redo log 是 Innodb 存储引擎特有)bin log 记录的是整个操作记录(这个对于主从复制具有非常重要的意义)首先执行器根据 MySQL 的执行计划来查询数据,先是从缓存池中查询数据,如果没有就会去数据库中查询,如果查询到了就将其放到缓存池中。

2023-12-22 17:34:07 1017

原创 【MYSQL】MYSQL 的学习教程(五)之 MySQL 索引底层:B+ 树详解

阶数:一个节点最多有多少个孩子节点。(一般用字母m表示)关键字:节点上的数值就是关键字度:一个节点拥有的子节点的数量。B- 树(B树)是一种平衡的多叉树,它比较适用于对外查找一颗 m 阶的 B- 树,有以下特征:根结点至少有两个子女;每个非根节点所包含的关键字个数 j 满足:⌈m/2⌉ - 1

2023-12-22 10:39:55 950

原创 【MYSQL】MYSQL 的学习教程(四)之索引失效场景

当操作符左右两边的数据类型不一致时,会发生隐式转换当查询字段为数值类型时发生了隐式转换,那么对效率影响不大,但还是不推荐这么做当查询字段为字符类型时发生了隐式转换,那么会导致索引失效,造成全表扫描效率极低字符串转换为数值类型时,非数字开头的字符串会转化为 0,以数字开头的字符串会截取从第一个字符到第一个非数字内容为止的值为转化结果所以,我们在写 SQL 时一定要养成良好的习惯,查询的字段是什么类型,等号右边的条件就写成对应的类型。

2023-12-20 10:16:55 1255

原创 【MYSQL】MYSQL 的学习教程(三)之索引核心知识点

回表:当查询的数据在索引树中,找不到的时候,需要回到主键索引树中去获取,这个过程叫做回表需要查询所有列的数据,idx_age 普通索引不能满足,需要拿到主键 id 的值后,再回到id主键索引查找获取,这个过程就是回表如果我们查询 SQL 的select *修改为的话,其实是不需要回表的。因为 id 和 age 的值,都在idx_age 索引树的叶子节点上覆盖索引是 select 的数据列只用从索引中就能够取得,不必回表,换句话说,查询列要被所建的索引覆盖。所以,在日常开发中,尽量不要。

2023-12-19 11:51:05 940

原创 【MYSQL】MYSQL 的学习教程(二) 之 MySQL InnoDB工作原理

在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。一个业务都会对应多张表,比如:学生和班级,起码两张表③:内连接和外连接的区别:假设 A 和 B 表进行连接。

2023-12-06 14:41:11 1084

原创 【MYSQL】MYSQL 的学习教程(一) 之 MYSQL 的逻辑架构解析

连接层为每个连接分配一个线程,该线程用来控制查询的执行。当连接通过用户名/密码的认证后,该连接可以发送 SQL 查询。连接层接受通过协议的应用程序连接。连接协议通过客户端的库及驱动实施,连接协议的速度因本地设置而异。上述协议中,MySQL 可以通过 TCP/IP 协议在网络间传送消息,其他的协议仅支持在本地使用(客户端和服务器必须在同一台主机上)TCP/IP协议除了用于网络间的远程连接,也可以用于本地连接。使用TCP/IP协议时需要使用IP地址或者DNS名称标识主机,并使用端口号标识服务。

2023-12-05 16:29:28 126

原创 【Redis】Redis 的学习教程(十三)Redis 各场景

由于Redis 支持比较丰富的数据结构,因此他能实现的功能并不仅限于缓存,而是可以运用到各种业务场景中,开发出既简洁、又高效的系统

2023-12-05 15:22:29 278

原创 【Redis】Redis 的学习教程(十二)之在 Redis使用 lua 脚本

基于 Redis 的分布式锁。

2023-09-28 16:14:50 1383

原创 【Redis】Redis 的学习教程(十一)之使用 Redis 实现分布式锁

在多线程环境下,为了保证数据的线程安全,锁保证同一时刻,只有一个可以访问和更新共享数据。在单机系统我们可以使用 synchronized 锁、Lock 锁保证线程安全。synchronized 锁是 Java 提供的一种内置锁,在单个 JVM 进程中提供线程之间的锁定机制,控制多线程并发。只适用于单机环境下的并发控制。想要在多个节点中提供锁定,在分布式系统并发控制共享资源,确保同一时刻只有一个访问可以调用,避免多个调用者竞争调用和数据不一致问题,保证数据的一致性,就需要。

2023-09-21 16:54:13 604

原创 【Redis】Redis 的学习教程(十)之使用 Redis 实现消息队列

消息队列需要满足的要求:Redis 提供了三种不同的方式来实现消息队列:因为 list 底层的实现就是一个「链表」,在头部和尾部操作元素,时间复杂度都是 O(1),这意味着它非常符合消息队列的模型如果你的业务需求足够简单,想把 Redis 当作队列来使用,肯定最先想到的就是使用 list 这个数据类型常用的命令:生产者:消费者:这个模型非常简单,如下图:当队列中已经没有消息了,消费者在执行 RPOP 时,会返回 NULL我们在编写消费者逻辑时,一般是一个「死循环」,这个逻辑需要不断地从队列中拉取消息进行处理

2023-09-18 16:00:07 2683 2

原创 【Redis】Redis 的学习教程(九)之 发布 Pub、订阅 Sub

订阅消息就是接收消息,这个比较复杂。既有对 Redis 连接的管理,也有对消费消息的线程池的管理。不过 Spring 已经把这个“重活”给干了。订阅/取消订阅这些相关的用户操作接收所有来自Redis的消息把这些消息按照订阅关系分发给具体的消费者触发消费消息的回调代码在线程池中运行由于 Spring 已经全权代理,用户只需要提供要消费的 topic 以及对应的消费回调代码即可。Topic接口,表示一个订阅对象:它有两个实现类,和。

2023-09-11 15:01:33 1324

原创 【Redis】Redis 的学习教程(八)之 BitMap、Geo、HyperLogLog

BitMap (位图)的底层数据结构使用的是String类型的的 SDS 数据结构来保存。因为一个字节 8 个 bit 位,为了有效的将字节的 8 个 bit 都利用到位,使用数组模式存储并且每个 bit 都使用二值状态表示,要么 0,要么 1所以,BitMap 是通过一个 bit 位来表示某个元素对应的值或者状态, 它的结构如下,key 对应元素本身;offset即是偏移量,固定整型,一般存数组下表或者唯一值;value存储的是二值(要么0要么1),一般用来表示状态,如性别、是否登录、是否打卡等。

2023-09-11 09:27:51 346

原创 【Redis】Redis 的学习教程(七)之 SpringBoot 集成 Redis

为了可读性,可以使用类,但有一个要求:key、value 都要求是 String 类型。但这就有一个问题,我们平时用得对象比较多,那又如何存储对象呢?@Override存 Redis 之前,将 Java 对象转换为 Json 字符串;读取后,将 Json 字符串转换为 Java 对象。这样做确实可行,但是,如果要存储的对象较多的话,那岂不是要重复地将 Java 对象转换为 Json 字符串?这样是不是很繁琐?继续看源码,发现被注入的被注解修饰:如果 Spring 容器中有了。

2023-08-31 11:38:32 2054 1

原创 【Redis】Redis 的学习教程(六)Redis 的缓存问题

自定义分布式布隆过滤器的存储依赖于 Redis 的 Bitmap 数据结构来实现,另外还需要定义四个参数,分别为预估数据量 size,误判率 fpp,数组大小 bitNum 以及 hash 函数个数 hashNum。其中,预估数据量和误判率需要配置在 yml 文件中。bloom:filter:fpp: 0.01@Component@Autowired/*** 预估数据量*//*** 误判率*//*** 数组大小len*//*** hash函数个数size*/

2023-08-31 10:52:01 540

原创 【Redis】Redis 的学习教程(五)之 Redis 事务、持久化、集群

RDB 持久化方式:能够在指定的时间间隔能对你的数据进行快照存储AOF 持久化方式:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。AOF 命令以 Redis 协议追加保存每次写的操作到文件末尾。Redis还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大。

2023-08-31 10:51:07 248

原创 【Redis】Redis 的学习教程(四)之 Redisson

在前几篇文章中,我们详细的介绍了 Jedis、Lettuce,我们不禁会发出一个疑问:Redisson和Jedis、Lettuce有什么区别?现在我们再回头来总结一番!Jedis:Redis 官方推出的用于通过 Java 连接 Redis 客户端的一个工具包,它提供了全面的类似于 Redis 原生命令的支持,是目前使用最广的一款 java 客户端。

2023-08-17 13:44:00 473

原创 【Redis】Redis 的学习教程(三)之 Lettuce

Lettuce 是 Redis 的一款高级 Java 客户端,与 Jedis 并列成为最热门的客户端之一,目前已成为 SpringBoot 2.0 版本默认的 redis 客户端相比老牌 Jedis,Lettuce 属于后起之秀,不仅功能丰富,而且提供了很多新的功能特性,比如异步操作、响应式编程等等,同时还解决了 Jedis 中线程不安全的问题。

2023-08-17 13:43:35 401

原创 【Redis】Redis 的学习教程(二)之 Jedis

Jedis 客户端是目前使用最广泛的一款 java 客户端,也是老牌的 Redis 的 Java 实现客户端。比较全面的提供了 Redis 的操作特性,也就是说你能用 redis 命令操作的,Jedis 包都也给你封装好了,直接使用即可使用广泛,易上手Jedis 客户端实例不是线程安全的,需要借助连接池来管理和使用 Jedis使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到 sockets 处理完 I/O 才能执行,不支持异步。

2023-08-17 13:43:13 188

原创 【Redis】Redis 的学习教程(一)入门基础

是一款开源的,遵守 BSD 协议,使用 C 语言开发的 key-value 存储系统。简单的说,它是一款跨平台的非关系型数据库,支持优先内存存储,在分布式的架构环境下,Redis 基本上是缺一不可的缓存中间件,它能很好的解决服务与服务之间数据共享的问题,并且性能不受影响。

2023-08-17 13:42:49 265

原创 【SpringCloud Alibaba】(七)学习 Sentinel 核心技术与配置规则(上)

在之前的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。也基于阿里开源的Sentinel实现了服务的限流与容错。今天,就和大家一起来聊聊Sentinel的核心技术与配置规则。

2023-08-02 09:49:31 354

原创 【SpringCloud Alibaba】(六)使用 Sentinel 实现服务限流与容错

今天,我们就使用 Sentinel 实现接口的限流,并使用 Feign 整合 Sentinel 实现服务容错的功能,让我们体验下微服务使用了服务容错功能的效果。因为内容仅仅围绕着 SpringCloud Alibaba技术栈展开,所以,这里我们使用的服务容错组件是阿里开源的 Sentinel。当然,能够实现服务容错功能的组件不仅仅有 Sentinel,比如:Hystrix 和 Resilience4J 也能够实现服务容错的目的。

2023-07-29 15:30:45 1197

原创 【SpringCloud Alibaba】(五)服务雪崩与容错方案

在前面的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。

2023-07-29 09:39:12 252

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除