并发编程专题-基础-13、线程池
1. 自定义1.1. 四种自带线程池1.1.1. 阻塞队列无界 -fixed-single1.1.1.1. newFixedThreadPool-nThreads 1.1.1.2. newSingleThreadExecutor-1-1 1.1.2. 最大线程数无界 -cached-scheduled1.1.2.1. newCachedThreadPool 1.1.2.2. newScheduledThreadPool 1.1.3. ForkJoinPool1.1.3.1. newWorkStealingPool 创建一个拥有多个任务队列的线程池,可以减少连接数,创建当前可用 cpu 数量的线程来并行执行,适用于大耗时的操作,可以并行来执行 使用了一个无限队列来保存需要执行的任务,而线程的数量则是通过构造函数传入,如果没有向构造函数中传入希望的线程数量,那么当前计算机可用的 CPU 数量会被设置为线程数量作为默认值。 newWorkStealingPool 会创建一个含有足够多线程的线程池,来维持相应的并行级别,它会通过工作窃取的方式,使得多核的 CPU 不会闲置,总会有活着的线程让 ...
框架源码专题-RocketMQ-2、消息的清理
1. 消费完后的消息去哪里了?消息的存储是一直存在于CommitLog中的。而由于CommitLog是以文件为单位(而非消息)存在的,CommitLog的设计是只允许顺序写的,且每个消息大小不定长,所以这决定了消息文件几乎不可能按照消息为单位删除(否则性能会极具下降,逻辑也非常复杂)。所以消息被消费了,消息所占据的物理空间并不会立刻被回收。 但消息既然一直没有删除,那RocketMQ怎么知道应该投递过的消息就不再投递?——答案是客户端自身维护——客户端拉取完消息之后,在响应体中,broker会返回下一次应该拉取的位置,PushConsumer通过这一个位置,更新自己下一次的pull请求。这样就保证了正常情况下,消息只会被投递一次。 2. 什么时候清理物理消息文件?那消息文件到底删不删,什么时候删? 消息存储在CommitLog之后,的确是会被清理的,但是这个清理只会在以下任一条件成立才会批量删除消息文件(CommitLog): 消息文件过期(默认72小时),且到达清理时点(默认是凌晨4点),删除过期文件。 消息文件过期(默认72小时),且磁盘空间达到了水位线(默认75%),删除过期文 ...
框架源码专题-RocketMQ-3、消息ACK机制及消费进度管理
1. 消息类型1.1. 顺序消费 (顺序消息)%%▶5.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230417-1521%%❕ ^gmi3ab https://www.bilibili.com/video/BV1L4411y7mn?p=24&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204 顺序消息指的是,严格按照消息的发送顺序进行消费的消息 (FIFO)。默认情况下生产者会把消息以 Round Robin 轮询方式发送到不同的 Queue 分区队列;而消费消息时会从多个 Queue 上拉取消息,这种情况下的发送和消费是不能保证顺序的。如果将消息仅发送到同一个 Queue 中,消费时也只从这个 Queue 上拉取消息,就严格保证了消息的顺序性。 当发送和消费参与的 queue 只有一个,则是全局有序;如果多个 queue 参与,则为分区有序,即相对每个 queue,消息都是有序的。 下面用订单进行分区有序的示例。一个订单的顺序流程是:创建、付款、推送、完成。订单号相同的消息会被先后发送到同一个队列中,消费时,同一 ...
框架源码专题-MySQL-1、基本原理
1. SQL 分类https://www.jianshu.com/p/671a2d54dca0 DQL:查询DML:增删改DDL: (Data Definition Language 数据定义语言)用于操作对象及对象本身,这种对象包括数据库,表对象,及视图对象DCL:(Data Control Language 数据控制语句) 用于操作数据库对象的权限,比如:greate: 分配权限给用户revoke: 废除数据库中某用户的权限 2. MySQL 结构 3. 内部原理[[Mysql面试题#^jerwaj]] https://learnku.com/docs/daily-qa/2021-07-16-why-do-redo-logs-need-to-be-submitted-in-two-phases/11200 https://blog.csdn.net/weixin_40471676/article/details/119732738 3.1. 查询过程https://xiaolincoding.com/mysql/base/how_select.htm ...
框架源码专题-RocketMQ-1、基本原理
1. 历史 Kafka:一个 topic 中每个 Queue 都是一个单独的文件,所有消息都存在其中RocketMQ:所有 topic 所有 Queue 的消息都放在一种文件中,即 CommitLog,默认大小为 1G。但又为每个 topic 创建一个目录,然后为每个 Queue 创建一个文件,即 ConsumeQueue,用来存储索引信息。存储使用 CommitLog,查询使用 ConsumeQueue。实现了读写分离。 2. 基本概念2.1. 消息(Message)消息是指,消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。 2.2. 主题(Topic)- 消费者 - 消费者组Topic 表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是 RocketMQ 进行消息订阅的基本单位。 topic:message 1:n message : topic 1:1一个生产者可以同时发送多种 Topic 的消息;而一个消费者只对某种特定的 Topic 感兴趣,即只可以订阅和消费一种 Topic 的消息。 produce ...
分布式专题-2、分布式事务
1. 是什么 分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务,例如用户注册送积分 事务、创建订单减库存事务,银行转账事务等都是分布式事务。 2. 产生的场景典型的场景就是微服务架构 微服务之间通过远程调用完成事务操作。 比如:订单微服务和库存微服务,下单的同时订单微服务请求库存微服务减库存。 简言之:跨 JVM 进程产生分布式事务。 单体系统访问多个数据库实例 当单体系统需要访问多个数据库(实例)时就会产生分布式事务。 比如:用户信息和订单信息分别在两个 MySQL 实例存储,用户管理系统删除用户信息,需要分别删除用户信息及用户的订单信 息,由于数据分布在不同的数据实例,需要通过不同的数据库链接去操作数据,此时产生分布式事务。 简言之:跨 数据库实例产生分布式事务。 多服务访问同一个数据库实例 比如:订单微服务和库存微服务即使访问同一个数据库也会产生分布式事务,原 因就是跨 JVM 进程,两个微服务持有了不同的数据库链接进行数据库操作,此时产生分布式事务 ...
Java基础-基本原理-4、泛型
1. 什么是泛型1.1. 背景JAVA 推出泛型以前,程序员可以构建一个元素类型为 Object 的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型,否则很容易引发 ClassCastException 异常。 1.2. 概念Java 泛型(generics)是 JDK5 中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。 1.3. 好处类型安全 消除了强制类型的转换 1.4. 类型E - Element (在集合中使用,因为集合中存放的是元素)T - Type(表示 Java 类,包括基本的类和我们自定义的类)K - Key(表示键,比如 Map 中的 key)V - Value(表示值)N - Number(表示数值类型)? - (表示不确定的 java 类型)S、U、V - 2nd、3rd、4th types 2. 泛型类和接口2.1. 泛型类 2.2. 泛型接口 3. 泛型方法返回值前面加泛型列表 4. ...
框架源码专题-Redis-2、分布式锁与秒杀优化
1. 超卖问题 2. 分布式锁 2.1. Zookeeper 实现服务注册与发现-12、Zookeeper 3. Redis 分布式锁 -set nx ex- 存在问题⭐️🔴3.1. 删除其他线程的锁3.1.1. 发生原因 3.1.2. 解决方案 3.2. 优化线程 ID 3.3. 系统阻塞导致删锁3.3.1. 发生原因 3.3.2. 解决方案保证判断和释放动作的原子性 3.3.3. 不可重入 3.4. 问题总结⭐️🔴 比较容易解决的问题: 加锁与设置有效期设为原子操作 锁归属判断,防止误删其他线程的锁 判断锁归属与 unlock 动作设为原子操作 但是还是有其他问题: 不可重入 不可重试 超时释放,自动续期 主从一致性 所以引入 Redisson 或者 ZK 的分布式锁实现方案 4. Redisson4.1. 使用 4.2. 可重入原理4.2.1. 不可重入原因 4.2.2. 解决办法 4.3. 看门狗原理https://www.bilibili.com/video/BV1cr4y1671t/?p=67&spm_id_from=pageDriver&am ...
框架源码专题-Redis-1、基本原理
1. 数据类型1.1. String- 点赞 setex: 设置带过期时间的 key,动态设置。setex 键秒值真实值 setnx: 只有在 key 不存在时设置 key 的值 点赞 1.2. List- 关注列表 一个双端链表的结构,容量是 2 的 32 次方减 1 个元素,大概 40 多亿,主要功能有 push/pop 等,一般用在栈、队列、消息队列等场景。 left、right 都可以插入添加;如果键不存在,创建新的链表;如果键已存在,新增内容; 如果值全移除,对应的键也就消失了。 它的底层实际是个 双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差 1 大 V 作者李永乐老师和 CSDN 发布了文章分别是 11 和 222 阳哥关注了他们两个,只要他们发布了新文章,就会安装进我的 List lpush likearticle:阳哥id 11 223 查看阳哥自己的号订阅的全部文章,类似分页,下面 0~10 就是一次显示 10 条 lrange likearticle:阳哥id 0 9 1.3. Hash- 购物车 1.4. Se ...
并发编程专题-基础-12、AQS
1. 是什么 1.1. 大致结构在 AbstractQueuedSynchronizer 类中,有几个属性和一个双向队列(CLH 队列) AQS 就是并发包下的一个基类 AQS = state + CLH 队列 Node = waitStatud + Thread 1.2. 涉及锁 1.3. 模板设计模式由子类实现具体方法逻辑 1.4. 类关系图 1.5. 加锁过程 如果是第一个线程 t1,那么和队列无关,线程直接持有锁。并且也不会初始化队列,如果接下来的线程都是交替执行,那么永远和 AQS 队列无关,都是直接线程持有锁 如果发生了竞争,比如 t1 持有锁的过程中 t2 来 lock,那么这个时候就会初始化 AQS,初始化 AQS 的时候会在队列的头部虚拟一个 Thread 为 NULL 的 Node,因为队列当中的 head 永远是持有锁的那个 node(除了第一次会虚拟一个,其他时候都是持有锁的那个线程锁封装的 node) 现在第一次的时候持有锁的是 t1 ,而 t1 不在队列当中所以虚拟了一个 node 节点,队列当中的除了 head 之外的所有的 no ...


