📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。
🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。
一、并发编程知识体系
并发编程是计算机科学中一个非常重要的领域,它涉及到多个线程或进程在同一个时间段内执行多个任务,以提高系统的响应速度和资源利用率。下面将从线程基础、线程生命周期、线程优先级、守护线程、线程池、核心参数配置、拒绝策略、工作队列类型、同步机制、悲观锁/乐观锁、读写锁、条件变量、并发集合、并发工具类、非阻塞算法、CAS原理、Atomic类、无锁队列、并发框架等方面进行详细讲解。
- 线程基础
线程是程序执行的最小单元,是操作系统能够进行运算调度的最小单位。线程具有以下特点:
(1)线程拥有独立的栈空间、程序计数器、寄存器等资源,这些资源在创建线程时由操作系统进行分配; (2)线程可以并发执行,提高程序的执行效率,尤其是在多核处理器上; (3)线程之间可以共享内存,方便数据传递,但需要通过同步机制来保证数据的一致性。
- 线程生命周期
线程生命周期包括以下状态:
(1)新建(New):创建线程对象时,线程处于新建状态,此时线程还没有分配资源; (2)就绪(Runnable):线程获取到CPU资源,处于就绪状态,等待被调度执行; (3)运行(Running):线程正在执行,处于运行状态,此时线程正在占用CPU资源; (4)阻塞(Blocked):线程因为某些原因无法继续执行,处于阻塞状态,如等待资源、等待锁等; (5)等待(Waiting):线程主动进入等待状态,直到被其他线程唤醒; (6)超时等待(Timed Waiting):线程在指定时间内无法继续执行,处于超时等待状态; (7)终止(Terminated):线程执行完毕或被终止,处于终止状态。
线程在生命周期中的状态转换是通过操作系统内核调度实现的,线程状态转换的时机和原因可能包括:
- 线程请求资源失败,如等待锁、等待I/O操作完成等;
- 线程执行完毕,如完成任务、执行异常等;
- 线程被其他线程唤醒,如调用notify()、notifyAll()等;
- 线程主动进入等待状态,如调用wait()、sleep()等。
- 线程优先级
线程优先级决定了线程在CPU上的执行顺序。Java中,线程优先级分为以下级别:
(1)最低优先级(MIN_PRIORITY):1; (2)较低优先级(LOWER_PRIORITY):2; (3)默认优先级(NORM_PRIORITY):5; (4)较高优先级(HIGHER_PRIORITY):6; (5)最高优先级(MAX_PRIORITY):10。
线程优先级是一个相对值,不同的操作系统和JVM实现可能会有不同的优先级映射策略。在实际应用中,线程优先级主要用于影响线程调度的时机,而不是决定线程是否能够得到CPU资源。
- 守护线程
守护线程是一种特殊的线程,它不是程序中不可或缺的部分。当所有的非守护线程执行完毕后,程序也会随之终止。守护线程主要用于执行一些清理工作,如垃圾回收等。
在Java中,可以使用Thread.setDaemon(true)方法将线程设置为守护线程。需要注意的是,守护线程的创建和启动必须在启动守护线程之前完成,否则守护线程将无法创建。
- 线程池
线程池是一种管理线程的方式,它可以有效地降低系统资源消耗,提高程序执行效率。线程池的主要特点如下:
(1)复用线程:线程池中的线程在任务完成后不会被销毁,而是被保留在池中,以便下次任务执行时复用; (2)限制线程数量:线程池可以限制线程的数量,防止系统资源被耗尽; (3)管理线程:线程池可以管理线程的生命周期,如创建、销毁、暂停等。
线程池的常见实现包括:
- ThreadPoolExecutor:Java提供的线程池实现,支持核心线程数、最大线程数、空闲存活时间、工作队列、拒绝策略等参数配置;
- Executors:Java提供的线程池工厂类,提供了newCachedThreadPool()、newFixedThreadPool()、newSingleThreadExecutor()等工厂方法,方便创建不同类型的线程池。
- 核心参数配置
线程池的核心参数配置如下:
(1)核心线程数(corePoolSize):线程池中最小线程数,即使没有任务提交,线程池也会维护这么多线程; (2)最大线程数(maximumPoolSize):线程池中最大线程数,当任务数量超过核心线程数时,线程池会创建新的线程来处理任务; (3)空闲存活时间(keepAliveTime):空闲线程存活时间,超过这个时间的空闲线程将被回收; (4)工作队列(workQueue):线程池中的任务队列,用于存放等待执行的任务; (5)拒绝策略(RejectedExecutionHandler):当任务无法被线程池处理时的处理策略,如AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy等。
- 拒绝策略
拒绝策略包括以下几种:
(1)AbortPolicy:抛出RejectedExecutionException异常,表示拒绝执行任务; (2)CallerRunsPolicy:调用者运行策略,将任务回退给调用者执行; (3)DiscardPolicy:丢弃任务,不执行任何操作; (4)DiscardOldestPolicy:丢弃最久未执行的任务。
- 工作队列类型
工作队列类型包括以下几种:
(1)LinkedBlockingQueue:线程安全的无界队列,基于链表实现,适用于任务数量较多的情况; (2)ArrayBlockingQueue:线程安全的有限队列,基于数组实现,适用于任务数量有限的情况; (3)PriorityBlockingQueue:线程安全的优先队列,基于优先级堆实现,适用于需要按优先级执行任务的情况; (4)SynchronousQueue:线程安全的阻塞队列,基于阻塞算法实现,适用于任务数量较少的情况。
- 同步机制
同步机制包括以下几种:
(1)互斥锁(Mutex):保证在同一时刻,只有一个线程可以访问共享资源,如ReentrantLock、synchronized关键字等; (2)读写锁(ReadWriteLock):允许多个线程同时读取共享资源,但只有一个线程可以写入共享资源,如ReentrantReadWriteLock等; (3)条件变量(Condition):允许线程在某些条件下暂停执行,等待其他线程的通知,如ReentrantLock中的Condition接口等。
- 悲观锁/乐观锁
悲观锁和乐观锁是两种处理并发控制的方法:
(1)悲观锁:假设在执行过程中数据会被修改,因此对数据进行加锁处理,如synchronized关键字、ReentrantLock等; (2)乐观锁:假设在执行过程中数据不会被修改,因此使用版本号或时间戳等方式来保证数据的一致性,如CAS算法、乐观锁机制等。
- 读写锁
读写锁允许多个线程同时读取共享资源,但只有一个线程可以写入共享资源。读写锁的主要特点如下:
(1)读操作可以并发执行; (2)写操作独占执行; (3)读操作优先级高于写操作。
读写锁的实现通常基于互斥锁和条件变量,如ReentrantReadWriteLock等。
- 条件变量
条件变量允许线程在某些条件下暂停执行,等待其他线程的通知。条件变量通常与互斥锁配合使用,如ReentrantLock中的Condition接口等。
- 并发集合
并发集合是指支持多线程操作的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等。并发集合通过内部机制保证线程安全,如使用分段锁、读写锁、CAS算法等。
- 并发工具类
并发工具类包括以下几种:
(1)Phaser:用于控制多个线程的并发执行,如分阶段执行任务等; (2)Exchanger:用于线程间的数据交换,如生产者-消费者模式等; (3)FutureTask:用于异步执行任务,如线程池中的任务等; (4)非阻塞算法:如CompareAndSwap(CAS)算法,用于实现无锁编程。
- CAS原理
CAS(Compare-And-Swap)算法是一种无锁编程技术,它通过比较内存中某个变量的值和预期值,如果相等,则将新值写入内存。CAS算法主要包含以下三个操作:
(1)V:当前内存变量的值; (2)A:预期值; (3)B:新值。
- Atomic类
Atomic类是一组线程安全的类,用于实现无锁编程。例如,AtomicInteger、AtomicLong等。
- 无锁队列
无锁队列是指不使用互斥锁的队列,如ConcurrentLinkedQueue。无锁队列通过CAS算法等机制保证线程安全,适用于任务数量较少的情况。
- 并发框架
并发框架主要包括以下几种:
(1)Netty线程模型:基于事件驱动模型,提供高性能、可扩展的网络应用程序开发框架; (2)Akka Actor模型:基于Actor模型,实现无状态、有状态的Actor通信; (3)Disruptor环形缓冲区:基于环形缓冲区,提供高性能的消息传递机制。
二、MyBatis知识体系
MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。下面将从SQL映射、注解映射、结果集映射、关联查询、动态SQL、OGNL表达式、分支语句、批量操作、缓存机制、一级缓存、二级缓存、自定义缓存、代理模式、MapperProxy、插件拦截、动态代理、执行流程、SqlSession生命周期、执行器类型、延迟加载、扩展机制、类型处理器、拦截器链、方言支持等方面进行详细讲解。
- SQL映射
SQL映射是指将Java对象与数据库表进行映射的过程。MyBatis通过XML或注解的方式来实现SQL映射。
(1)XML映射:通过编写XML配置文件来定义SQL映射,包括SQL语句、参数映射、结果集映射等; (2)注解映射:通过在Java接口或实体类上添加注解来定义SQL映射,如@Select、@Insert、@Update、@Delete等。
- 注解映射
注解映射是MyBatis提供的一种映射方式,它通过在Java对象上添加注解来定义SQL映射。注解映射具有以下优点:
(1)简化配置:通过注解,可以减少XML配置文件的使用,提高开发效率; (2)易于维护:通过注解,可以清晰地表达映射关系,方便维护和修改。
- 结果集映射
结果集映射是指将数据库表中的数据映射到Java对象的过程。MyBatis通过XML或注解的方式来实现结果集映射。
(1)XML映射:通过编写XML配置文件来定义结果集映射,包括字段映射、类型处理器等; (2)注解映射:通过在Java实体类上添加注解来定义结果集映射,如@Results、@Result等。
- 关联查询
关联查询是指将多个表的数据进行关联查询的过程。MyBatis通过XML或注解的方式来实现关联查询。
(1)XML映射:通过编写XML配置文件来定义关联查询,包括一对一、一对多、多对多等关联关系; (2)注解映射:通过在Java实体类上添加注解来定义关联查询,如@One、@Many等。
- 动态SQL
动态SQL是指根据条件动态生成SQL语句的过程。MyBatis通过OGNL表达式、分支语句、片段等方式来实现动态SQL。
(1)OGNL表达式:OGNL(Object-Graph Navigation Language)是一种表达式语言,用于在MyBatis中实现动态SQL,如@SelectProvider、@UpdateProvider等; (2)分支语句:通过使用if、choose、when、otherwise等分支语句,根据条件动态生成SQL语句; (3)片段:将重复的SQL片段封装起来,方便复用。
- OGNL表达式
OGNL(Object-Graph Navigation Language)是一种表达式语言,它允许在MyBatis中动态地访问对象属性、执行方法、调用函数等。OGNL表达式具有以下特点:
(1)支持对象属性访问、方法调用、函数调用等; (2)支持条件判断、循环、集合操作等; (3)支持动态类型转换、类型安全等。
- 分支语句
分支语句用于在动态SQL中根据条件执行不同的SQL语句。MyBatis支持以下分支语句:
(1)if:根据条件判断是否执行SQL语句; (2)choose、when、otherwise:类似于Java中的switch语句,根据条件执行不同的SQL语句; (3)trim、where、set:用于动态地修改SQL语句的结构。
- 批量操作
批量操作是指一次性执行多个SQL语句的过程。MyBatis通过XML或注解的方式来实现批量操作。
(1)XML映射:通过编写XML配置文件来定义批量操作,如@Batch、@InsertBatch、@UpdateBatch等; (2)注解映射:通过在Java接口或实体类上添加注解来定义批量操作,如@BatchInsert、@BatchUpdate等。
- 缓存机制
MyBatis提供了两种缓存机制:一级缓存和二级缓存。
(1)一级缓存:MyBatis默认的缓存机制,它缓存了查询结果集。一级缓存的作用域是SqlSession,当SqlSession关闭后,一级缓存也会随之失效; (2)二级缓存:MyBatis提供的另一种缓存机制,它缓存了查询结果集的映射结果。二级缓存的作用域是Mapper,当Mapper关闭后,二级缓存也会随之失效。
- 一级缓存
一级缓存是MyBatis默认的缓存机制,它缓存了查询结果集。一级缓存的作用域是SqlSession,当SqlSession关闭后,一级缓存也会随之失效。
一级缓存的工作原理如下:
(1)当执行查询操作时,MyBatis首先会检查一级缓存中是否存在该查询的结果集; (2)如果一级缓存中存在该查询的结果集,则直接从一级缓存中获取结果集,避免再次查询数据库; (3)如果一级缓存中不存在该查询的结果集,则执行数据库查询操作,并将查询结果集缓存到一级缓存中。
- 二级缓存
二级缓存是MyBatis提供的另一种缓存机制,它缓存了查询结果集的映射结果。二级缓存的作用域是Mapper,当Mapper关闭后,二级缓存也会随之失效。
二级缓存的工作原理如下:
(1)当执行查询操作时,MyBatis首先会检查二级缓存中是否存在该查询的结果集映射结果; (2)如果二级缓存中存在该查询的结果集映射结果,则直接从二级缓存中获取映射结果,避免再次执行SQL语句; (3)如果二级缓存中不存在该查询的结果集映射结果,则执行SQL语句,并将查询结果集的映射结果缓存到二级缓存中。
- 自定义缓存
自定义缓存是指根据需求自定义缓存机制,如Redis缓存。自定义缓存可以提供更丰富的缓存策略和功能,如分布式缓存、缓存穿透、缓存雪崩等。
- 代理模式
代理模式是指使用代理对象来代替目标对象,实现对目标对象的控制。在MyBatis中,代理模式主要用于实现动态代理,如MapperProxy。
- MapperProxy
MapperProxy是MyBatis中用于实现代理模式的一个类。它通过代理模式实现了Mapper接口的动态代理,从而实现了延迟加载、缓存等功能。
- 插件拦截
MyBatis插件拦截是指在执行SQL语句的过程中,拦截特定操作,实现自定义逻辑。插件拦截可以用于实现日志记录、性能监控、参数校验等功能。
- 动态代理
动态代理是一种在运行时创建代理对象的技术。在MyBatis中,动态代理主要用于实现Mapper接口的代理,从而实现延迟加载、缓存等功能。
- 执行流程
MyBatis的执行流程包括以下步骤:
(1)解析XML配置文件:MyBatis会解析XML配置文件,包括SQL映射、缓存配置、插件配置等; (2)生成SqlSession:SqlSession是MyBatis的核心对象,它负责执行SQL语句、管理事务等; (3)执行SQL语句:MyBatis会根据SQL映射和参数信息,生成SQL语句,并执行SQL语句; (4)处理结果集:MyBatis会处理SQL语句的执行结果,包括结果集映射、类型转换等; (5)关闭SqlSession:执行完毕后,MyBatis会关闭SqlSession,释放资源。
- SqlSession生命周期
SqlSession的生命周期包括以下阶段:
(1)创建SqlSession:通过SqlSessionFactory创建SqlSession; (2)执行SQL语句:使用SqlSession执行SQL语句,包括查询、更新、删除等; (3)提交或回滚事务:根据操作结果,提交或回滚事务; (4)关闭SqlSession:关闭SqlSession,释放资源。
- 执行器类型
MyBatis提供了多种执行器类型,如SimpleExecutor、ReuseExecutor、BatchExecutor等。
(1)SimpleExecutor:简单执行器,适用于单条SQL语句执行; (2)ReuseExecutor:重用执行器,适用于多条SQL语句执行,它会重用预处理语句和连接; (3)BatchExecutor:批处理执行器,适用于批量操作,它会将多条SQL语句合并为一条批量SQL语句执行。
- 延迟加载
延迟加载是指将关联数据在需要时才加载,以提高程序执行效率。在MyBatis中,可以通过@Lazy注解来实现延迟加载。
- 扩展机制
MyBatis提供了扩展机制,允许用户自定义插件、拦截器等。
(1)插件:MyBatis插件可以拦截MyBatis的执行过程,实现自定义逻辑,如日志记录、性能监控等; (2)拦截器:MyBatis拦截器可以拦截MyBatis的执行过程,实现自定义逻辑,如参数校验、类型转换等。
- 类型处理器
类型处理器是指将Java类型与数据库类型进行转换的机制。MyBatis提供了多种类型处理器,如StringTypeHandler、DateTypeHandler等。
- 拦截器链
拦截器链是指将多个拦截器按照顺序连接起来,形成一个拦截器链。在MyBatis中,拦截器链可以用于实现自定义逻辑,如日志记录、性能监控等。
- 方言支持
方言支持是指MyBatis对特定数据库的SQL语句进行适配。MyBatis提供了多种方言支持,如MySQL方言、Oracle方言等。
总结
本文详细讲解了并发编程和MyBatis相关知识体系,从线程基础、线程生命周期、线程优先级、守护线程、线程池、核心参数配置、拒绝策略、工作队列类型、同步机制、悲观锁/乐观锁、读写锁、条件变量、并发集合、并发工具类、非阻塞算法、CAS原理、Atomic类、无锁队列、并发框架等方面进行了阐述。同时,对MyBatis的SQL映射、注解映射、结果集映射、关联查询、动态SQL、OGNL表达式、分支语句、批量操作、缓存机制、一级缓存、二级缓存、自定义缓存、代理模式、MapperProxy、插件拦截、动态代理、执行流程、SqlSession生命周期、执行器类型、延迟加载、扩展机制
📥博主的人生感悟和目标
- 💂 博客主页: Java程序员廖志伟希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 👉 开源项目: Java程序员廖志伟
- 🌥 哔哩哔哩: Java程序员廖志伟
- 🎏 个人社区: Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD
📙经过多年在优快云创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码--沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!
🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

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



