📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。
🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。
一、并发编程知识体系
在深入探讨并发编程之前,我们首先需要构建一个全面的知识体系,这将帮助我们更好地理解和应用并发编程技术。
线程基础
线程是并发编程的核心概念,它是程序执行的最小单元。在现代操作系统中,线程是由内核管理的轻量级执行单位,它共享进程的资源,但具有自己的执行栈、寄存器和状态信息。
线程生命周期:线程从创建到销毁会经历多个状态,包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)和终止(Terminated)。
- 新建状态:线程创建时进入新建状态,此时线程的CPU状态为空,操作系统为其分配必要的资源。
- 就绪状态:线程等待被调度执行的状态,此时线程已准备好运行,等待获得CPU资源。
- 运行状态:线程正在执行,获得CPU时间片。
- 阻塞状态:线程因某些原因(如等待锁)而无法继续执行。
- 等待状态:线程主动进入等待状态,等待某个条件成立。
- 超时等待状态:线程等待某个条件成立,但设置了超时时间,超时后线程退出等待状态。
- 终止状态:线程执行完毕,释放资源,操作系统回收。
线程优先级:线程优先级决定了线程在CPU调度时的优先级,Java中通过Thread类的getPriority()和setPriority()方法来获取和设置线程优先级。线程优先级分为1到10,数字越大,优先级越高。然而,优先级并不保证线程一定能得到CPU资源,只是操作系统进行调度的依据之一。
守护线程:守护线程是服务于其他线程的线程,当所有非守护线程结束时,程序将退出,守护线程也会自动结束。Java虚拟机保证在主线程结束后,守护线程一定会结束,但不会等待守护线程完成执行。
线程池:线程池是管理一组线程的集合,它可以提高应用程序的响应速度,并减少系统创建线程的开销。
- 核心参数配置:包括核心线程数、最大线程数、线程活跃时间、队列容量等。核心线程数是线程池的最小线程数,最大线程数是线程池的最大线程数,线程活跃时间是指线程被创建到销毁的时间,队列容量是指工作队列的最大容量。
- 拒绝策略:当线程池达到最大容量时,如何处理新提交的任务。拒绝策略有四种:AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy。
- 工作队列类型:包括直接提交队列、有界队列、无界队列、优先队列等。直接提交队列是指没有额外线程创建,直接将任务提交给工作队列;有界队列是指有最大容量限制,当工作队列满时,线程池会根据拒绝策略处理任务;无界队列是指没有容量限制,但会创建额外的线程处理任务;优先队列是指根据任务的优先级进行调度。
同步机制
同步机制是确保多个线程安全访问共享资源的重要手段。
悲观锁/乐观锁:悲观锁假设冲突很可能会发生,因此总是先加锁;乐观锁假设冲突很少发生,因此只在需要时才加锁。
- 悲观锁:悲观锁主要解决线程之间对共享资源修改的冲突,常见的悲观锁实现方式有锁机制(如互斥锁、读写锁)和版本控制。
- 锁机制:锁机制包括互斥锁(Mutex)、读写锁(Reader-Writer Lock)、可重入锁(Reentrant Lock)等,通过限制对共享资源的并发访问来保证线程安全。
- 版本控制:版本控制是通过维护资源的版本号来避免并发修改冲突,常见的方式有乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)。
- 乐观锁:乐观锁主要解决线程之间对共享资源读取的冲突,常见的方式有CAS(Compare-And-Swap)操作。
- CAS操作:CAS操作通过比较内存中的值和预期的值,如果相等,则更新内存中的值。
读写锁:读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。读写锁包括共享锁(读锁)和独占锁(写锁)。
- 共享锁:共享锁允许多个线程同时读取共享资源,但不允许写入。
- 独占锁:独占锁只允许一个线程访问共享资源,无论是读取还是写入。
条件变量:条件变量允许线程在某个条件不满足时挂起,直到条件满足时被唤醒。条件变量通常与锁机制一起使用,确保线程在等待条件满足时不会被其他线程中断。
并发集合
并发集合是专为并发环境设计的集合类,例如ConcurrentHashMap、CopyOnWriteArrayList等。
- ConcurrentHashMap:ConcurrentHashMap是基于分段锁(Segment Lock)实现的线程安全的哈希表,它将数据分成多个段,每个段都有自己的锁,从而减少锁竞争,提高并发性能。
- CopyOnWriteArrayList:CopyOnWriteArrayList是基于写时复制(Write-Through)实现的线程安全的列表,每次修改操作都会复制原列表,从而保证线程安全。
并发工具类
Phaser:Phaser是一个可重入的同步屏障,用于协调多个线程的执行。
- 同步屏障:同步屏障是指线程在执行到同步屏障时必须等待其他线程通过该屏障,从而保证屏障前的任务在屏障后完成。
- 可重入性:Phaser支持线程在执行到同步屏障时,如果已经持有Phaser的引用,可以再次进入Phaser。
Exchanger:Exchanger允许两个线程在某个节点上交换数据。
- 交换数据:两个线程到达交换节点后,各自将自己携带的数据传递给对方,并接收对方的数据。
FutureTask:FutureTask是一个可以表示异步计算结果的类。
- 异步计算:FutureTask可以将计算任务提交给线程池,线程池会创建一个线程执行该任务,并将计算结果存储在FutureTask中,从而实现异步计算。
非阻塞算法
非阻塞算法利用CAS(Compare-And-Swap)操作实现无锁编程。
- CAS原理:CAS操作通过比较内存中的值和预期的值,如果相等,则更新内存中的值。CAS操作包含三个操作数:内存地址、预期值和新值。如果内存地址的值等于预期值,则将内存地址的值更新为新值,否则不执行任何操作。
- Atomic类:Atomic类提供了一系列原子操作,如
AtomicInteger、AtomicLong等。这些原子类使用CAS操作保证线程安全。 - 无锁队列:无锁队列利用CAS操作实现队列的插入和删除操作。无锁队列不需要锁机制,从而提高并发性能。
并发框架
Netty线程模型:Netty采用主从多线程模型,主线程负责处理连接,从线程负责处理读写操作。
- 主从多线程模型:主从多线程模型将线程分为两类:主线程和从线程。主线程负责处理连接建立、销毁和心跳等操作,从线程负责处理读写操作。
Akka Actor模型:Akka采用Actor模型,每个Actor都是一个消息处理器,通过消息传递进行通信。
- Actor模型:Actor模型是一种并发模型,它将程序划分为多个Actor,每个Actor负责处理自己的消息,通过发送和接收消息进行通信。
Disruptor环形缓冲区:Disruptor使用环形缓冲区来存储数据,通过CAS操作实现高效的并发访问。
- 环形缓冲区:环形缓冲区是一种固定大小的数据结构,它使用环形数组存储数据,并提供索引操作。
- CAS操作:Disruptor使用CAS操作实现线程安全的环形缓冲区,从而提高并发性能。
二、MyBatis知识体系
MyBatis是一个强大的持久层框架,它消除了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作。
SQL映射
MyBatis通过XML或注解的方式将SQL映射到Java对象。
- 注解映射:使用
@Select、@Insert、@Update、@Delete等注解来映射SQL语句。- @Select:用于映射查询SQL语句。
- @Insert:用于映射插入SQL语句。
- @Update:用于映射更新SQL语句。
- @Delete:用于映射删除SQL语句。
- 结果集映射:通过
<resultMap>元素定义复杂类型的映射关系。- 类型处理器:MyBatis使用类型处理器将数据库类型转换为Java类型。
- 自定义类型处理器:通过实现
TypeHandler接口自定义类型处理器。
- 关联查询:使用
<association>或<collection>元素进行一对一或一对多关联查询。- 一对一关联查询:使用
<association>元素进行一对一关联查询。 - 一对多关联查询:使用
<collection>元素进行一对多关联查询。
- 一对一关联查询:使用
- 动态SQL:使用
<if>、<choose>、<when>、<otherwise>等元素实现动态SQL。- `元素 :用于根据条件判断是否执行SQL语句。
- `元素 :用于实现条件分支。
- `元素 :用于实现条件分支。
- `元素 :用于实现条件分支的默认操作。
OGNL表达式
OGNL(Object-Graph Navigation Language)是一种表达式语言,用于在MyBatis中动态访问对象属性。
- OGNL表达式:OGNL表达式是一种基于属性和方法的表达式语言,用于动态访问对象属性。
- 分支语句:使用
<choose>、<when>、<otherwise>实现条件分支。- `元素 :用于实现条件分支。
- `元素 :用于实现条件分支。
- `元素 :用于实现条件分支的默认操作。
- 批量操作:使用
<foreach>元素实现批量插入、更新等操作。- `元素 :用于实现批量操作。
缓存机制
MyBatis提供一级缓存和二级缓存机制。
- 一级缓存:SqlSession级别的缓存,用于缓存同一个SqlSession中的数据。
- 缓存失效条件:当SqlSession关闭或提交/回滚事务时,一级缓存失效。
- 二级缓存:Mapper级别的缓存,用于缓存不同SqlSession中的数据。
- 缓存失效条件:当SqlSession关闭、提交/回滚事务、更新/删除数据或执行查询时,二级缓存失效。
- 自定义缓存:通过实现
Cache接口自定义缓存。 - 代理模式:MyBatis使用代理模式来封装SQL执行过程。
- 代理模式:代理模式是一种设计模式,它为其他对象提供一种代理以控制对这个对象的访问。
MapperProxy插件拦截
MapperProxy:MyBatis使用MapperProxy来代理Mapper接口,实现动态代理。
- 动态代理:动态代理是一种代理机制,它允许在运行时创建代理对象来代理某个类的方法调用。
- MapperProxy:MapperProxy是一个代理类,它代理Mapper接口的方法调用,并在方法调用前或后执行自定义逻辑。
插件拦截:通过实现Interceptor接口自定义插件,拦截SQL执行过程。
- Interceptor接口:Interceptor接口定义了拦截器的方法,如
intercept()、plugin()等。 - 拦截器链:MyBatis使用拦截器链来拦截SQL执行过程,拦截器链中的拦截器按照顺序执行,每个拦截器都有机会修改SQL执行过程。
动态代理执行流程:MyBatis通过动态代理技术拦截Mapper接口的方法调用,执行SQL语句。
SqlSession生命周期
SqlSession是MyBatis的核心对象,它管理着数据库连接、事务等。
- 执行器类型:MyBatis提供多种执行器类型,如SimpleExecutor、ReuseExecutor、BatchExecutor等。
- SimpleExecutor:SimpleExecutor使用预处理语句(PreparedStatement)来执行SQL语句,并重用预处理语句。
- ReuseExecutor:ReuseExecutor也使用预处理语句,但它重用预处理语句和数据库连接。
- BatchExecutor:BatchExecutor使用批量操作来提高SQL执行效率。
- 延迟加载:MyBatis支持延迟加载,在需要时才加载关联数据。
扩展机制
MyBatis提供多种扩展机制,如类型处理器、拦截器链、方言支持等。
- 类型处理器:MyBatis使用类型处理器将数据库类型转换为Java类型。
- 内置类型处理器:MyBatis内置了多种类型处理器,如
IntegerTypeHandler、StringTypeHandler等。 - 自定义类型处理器:通过实现
TypeHandler接口自定义类型处理器。
- 内置类型处理器:MyBatis内置了多种类型处理器,如
- 拦截器链:MyBatis使用拦截器链来拦截SQL执行过程,实现自定义功能。
- 拦截器:MyBatis拦截器是一个实现
Interceptor接口的类,它定义了拦截SQL执行过程的方法。
- 拦截器:MyBatis拦截器是一个实现
- 方言支持:MyBatis支持多种数据库方言,如MySQL、Oracle等。
通过以上知识体系的梳理,我们可以看到并发编程和MyBatis在设计和实现上有着紧密的联系。并发编程技术为MyBatis提供了高效的执行环境,而MyBatis则为并发编程提供了数据持久化的解决方案。在实际应用中,我们需要根据具体需求选择合适的并发编程技术和MyBatis配置,以达到最佳的性能和稳定性。
📥博主的人生感悟和目标
- 💂 博客主页: Java程序员廖志伟希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 👉 开源项目: Java程序员廖志伟
- 🌥 哔哩哔哩: Java程序员廖志伟
- 🎏 个人社区: Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD
📙经过多年在优快云创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码--沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!
🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~
717



被折叠的 条评论
为什么被折叠?



