📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

一、并发编程知识体系
线程基础
在并发编程中,线程是程序执行的最小单元,它允许程序同时执行多个任务。线程的创建和管理是并发编程的核心,其基本属性包括:
- 线程ID:线程ID是操作系统分配的唯一标识符,用于区分不同的线程。
- 线程状态:线程状态是线程执行过程中的一个状态,常见的状态包括新建、就绪、运行、阻塞、等待、超时和终止状态。线程状态之间的转换遵循特定的规则,例如,线程从就绪状态变为运行状态需要CPU的调度。
- 线程优先级:线程优先级是操作系统用来决定线程调度顺序的一个参数,它决定了线程被CPU调度的概率。线程优先级通常分为最大、正常、最小三个等级,操作系统会根据优先级来决定线程的执行顺序。
线程生命周期
线程从创建到销毁经历多个阶段,具体如下:
- 新建状态:线程通过
Thread
类或其子类构造方法创建,此时线程处于新建状态,线程的属性被初始化。 - 就绪状态:线程创建后,进入就绪状态,等待被CPU调度执行。线程就绪的条件包括:线程创建完成、线程优先级高于当前运行线程、线程等待的事件已发生。
- 运行状态:线程获得CPU时间开始执行任务,此时线程处于运行状态。线程在运行过程中可能会因为某些原因(如I/O操作)进入阻塞状态。
- 阻塞状态:线程由于某些原因(如I/O操作、等待锁等)无法执行,进入阻塞状态。线程在阻塞状态下不会占用CPU资源。
- 等待状态:线程在满足特定条件时主动放弃CPU时间,进入等待状态。线程在等待状态时不会占用CPU资源,但可以被其他线程唤醒。
- 终止状态:线程执行完毕或被强制终止,进入终止状态。处于终止状态的线程将不再被调度执行。
线程优先级
线程优先级是操作系统用来决定线程调度顺序的一个参数,它决定了线程被CPU调度的概率。线程优先级通常分为最大、正常、最小三个等级,操作系统会根据优先级来决定线程的执行顺序。线程可以通过setPriority()
方法设置优先级,但是需要注意的是,不同的操作系统和Java虚拟机对线程优先级的支持可能有所不同。
守护线程
守护线程是一种特殊的线程,它不会阻止程序终止。守护线程主要用于执行后台任务,如垃圾回收、日志记录等。在Java中,可以通过调用setDaemon(true)
方法将线程设置为守护线程。当JVM退出时,所有非守护线程都必须先终止,然后JVM才会退出。
线程池
线程池是管理一组线程的容器,它可以提高程序的性能。线程池的主要参数包括:
- 核心线程数:线程池中最小的工作线程数,线程池启动时创建的线程数。
- 最大线程数:线程池中允许的最大线程数,当任务数量超过核心线程数时,会创建新的线程来处理任务。
- 保持活跃时间:空闲线程的存活时间,超过这个时间后,空闲线程会被回收。
- 工作队列:存放等待执行的任务队列,常用的队列类型包括LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue等。
线程池的拒绝策略包括:
- AbortPolicy:抛出
RejectedExecutionException
异常,拒绝执行任务。 - CallerRunsPolicy:由调用者线程处理该任务,将任务提交给调用者线程。
- DiscardPolicy:直接丢弃任务,不抛出异常。
- DiscardOldestPolicy:丢弃最旧的任务,然后尝试执行新任务。
同步机制
同步机制用于解决多线程并发访问共享资源时出现的问题,主要包括:
- 悲观锁:假设数据在并发访问过程中可能会被修改,因此在访问前先加锁。悲观锁通常使用
synchronized
关键字或ReentrantLock
类实现。 - 乐观锁:假设数据在并发访问过程中不会发生冲突,因此在访问时检查数据是否被修改。乐观锁通常使用版本号或时间戳实现。
- 读写锁:允许多个线程同时读取数据,但只允许一个线程写入数据。读写锁可以提高并发性能,通常使用
ReentrantReadWriteLock
类实现。 - 条件变量:线程在满足特定条件时等待,条件满足时被唤醒。条件变量通常使用
Condition
类实现。
并发集合
Java提供了多种并发集合类,如ConcurrentHashMap
、CopyOnWriteArrayList
等,它们在并发环境下保证了线程安全。这些并发集合类通常采用以下技术实现线程安全:
- 分段锁:将数据分割成多个段,每个段使用独立的锁进行控制,从而提高并发性能。
- CAS操作:使用Compare-And-Swap(比较并交换)操作实现原子性,从而保证线程安全。
- 原子引用:使用
AtomicReference
等原子引用类实现线程安全。
并发工具类
- Phaser:Phaser是一个线程同步工具,它允许线程在执行过程中等待其他线程到达某个特定点。Phaser可以用于实现线程间的同步,例如,在并行计算中同步线程的执行。
- Exchanger:Exchanger是一个线程间交换数据的工具,它允许两个线程在某个点交换数据。Exchanger可以用于实现线程间的数据交换,例如,在多线程计算中交换中间结果。
- FutureTask:FutureTask是一个代表异步计算结果的并发工具,它允许调用者异步执行任务并获取结果。FutureTask可以用于实现异步编程,例如,在多线程任务中异步获取结果。
非阻塞算法
非阻塞算法基于CAS(Compare-And-Swap)原理,通过原子操作实现线程安全。CAS操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。当内存位置V的值与预期原值A相同时,将内存位置V的值修改为新值B,否则不做任何操作。
CAS原理
CAS操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。当内存位置V的值与预期原值A相同时,将内存位置V的值修改为新值B,否则不做任何操作。CAS操作具有以下特点:
- 原子性:CAS操作是原子的,即在整个操作过程中,其他线程无法观察到中间状态。
- 无锁:CAS操作不依赖于锁,可以减少锁的竞争,提高并发性能。
- 自旋:当CAS操作失败时,线程会进行自旋,即不断尝试重新执行CAS操作,直到成功为止。
Atomic类
Atomic
类提供了一系列的原子操作,如AtomicInteger
、AtomicLong
等。这些原子类可以保证在多线程环境下对基本数据类型的操作是线程安全的。
无锁队列
无锁队列是一种基于CAS操作的并发队列,如ConcurrentLinkedQueue
。无锁队列不需要使用锁,可以提供更高的并发性能。
并发框架
- Netty:Netty是一个高性能的NIO客户端/服务器框架,它提供了异步事件驱动的网络应用程序开发框架和工具。Netty使用Java NIO(Non-blocking I/O)技术,可以提供更高的并发性能和更好的扩展性。
- Akka:Akka是一个基于Actor模型的并发框架,它允许开发者在分布式系统中实现高并发、高可用和可扩展的应用程序。Akka使用Actor模型来模拟消息传递,可以提供更好的并发性能和可扩展性。
- Disruptor:Disruptor是一个高性能的环形缓冲区框架,它提供了高效的并发数据结构和算法。Disruptor使用环形缓冲区和CAS操作实现线程安全,可以提供更高的并发性能和更好的扩展性。
二、MyBatis知识体系
SQL映射
MyBatis通过XML或注解的方式定义SQL映射,将Java对象与数据库表进行映射。SQL映射包括以下内容:
- SQL语句:定义数据库操作所需的SQL语句,例如,查询、插入、更新、删除等。
- 参数映射:定义SQL语句中的参数与Java对象的属性之间的映射关系。
- 结果映射:定义数据库表中的数据与Java对象的属性之间的映射关系。
注解映射
MyBatis提供了多种注解,如@Select
、@Insert
、@Update
、@Delete
等,用于定义SQL映射。这些注解可以简化SQL映射的定义,提高开发效率。
结果集映射
MyBatis将数据库表中的数据映射到Java对象,包括字段映射、关联映射、嵌套映射等。结果集映射可以简化数据访问,提高开发效率。
关联查询
MyBatis支持多表关联查询,通过<resultMap>
元素定义关联关系。关联查询可以简化数据访问,提高开发效率。
动态SQL
MyBatis支持动态SQL,可以根据条件动态构建SQL语句。动态SQL可以简化SQL语句的定义,提高开发效率。
OGNL表达式
OGNL表达式用于在MyBatis中访问对象的属性和执行逻辑运算。OGNL表达式可以简化数据访问,提高开发效率。
分支语句
MyBatis支持条件分支语句,根据条件执行不同的SQL语句。条件分支语句可以简化SQL语句的定义,提高开发效率。
批量操作
MyBatis支持批量操作,可以提高数据库操作效率。批量操作可以减少数据库访问次数,提高数据库操作效率。
缓存机制
MyBatis提供了两种缓存机制:
- 一级缓存:本地缓存,用于存储查询结果。一级缓存可以减少数据库访问次数,提高查询效率。
- 二级缓存:分布式缓存,用于跨会话缓存数据。二级缓存可以减少数据库访问次数,提高查询效率,并支持跨会话缓存数据。
自定义缓存
MyBatis允许自定义缓存,通过实现Cache
接口实现。自定义缓存可以扩展MyBatis的缓存机制,满足特定的需求。
代理模式
MyBatis使用代理模式实现Mapper接口的动态代理,代理类负责执行SQL语句。代理模式可以简化Mapper接口的使用,提高开发效率。
MapperProxy
MapperProxy
是MyBatis中用于生成Mapper接口代理类的类。MapperProxy
可以简化Mapper接口的使用,提高开发效率。
插件拦截
MyBatis允许自定义插件,通过拦截SQL执行过程实现功能扩展。插件可以扩展MyBatis的功能,满足特定的需求。
动态代理执行流程
MyBatis使用CGLIB或JDK动态代理技术生成Mapper接口代理类,代理类负责执行SQL语句。动态代理可以简化Mapper接口的使用,提高开发效率。
SqlSession生命周期
SqlSession
是MyBatis的会话接口,负责执行SQL语句。SqlSession
的生命周期包括创建、使用和关闭。SqlSession
是MyBatis的核心组件,它负责管理数据库连接、事务和SQL语句的执行。
执行器类型
MyBatis提供了多种执行器类型,如简单执行器、批处理执行器、懒加载执行器等。不同的执行器类型适用于不同的场景,可以根据具体需求选择合适的执行器类型。
延迟加载
MyBatis支持延迟加载,在需要时才加载关联数据。延迟加载可以减少数据库访问次数,提高查询效率。
扩展机制
MyBatis提供了多种扩展机制,如类型处理器、拦截器链、方言支持等。扩展机制可以扩展MyBatis的功能,满足特定的需求。
通过以上知识点的串联,我们可以了解到并发编程和MyBatis在处理并发问题和数据库操作方面的优势和应用场景。在实际开发中,我们可以根据具体需求选择合适的并发编程模型和MyBatis配置,以提高程序的性能和可维护性。
📥博主的人生感悟和目标

- 💂 博客主页: Java程序员廖志伟希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 👉 开源项目: Java程序员廖志伟
- 🌥 哔哩哔哩: Java程序员廖志伟
- 🎏 个人社区: Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD

📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码--沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!
🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~