并发编程核心知识

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

Java程序员廖志伟

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

CSDN

一、并发编程知识体系

并发编程是现代计算机系统中的一个核心概念,它允许计算机在同一个时间段内处理多个任务,从而提高系统性能。以下是并发编程的一些基础知识点及其技术实现细节:

  1. 线程基础

线程是程序执行的基本单元,是操作系统能够进行运算调度的最小单位。线程具有以下特点:

  • 独立的栈空间和局部变量:每个线程都有自己的栈空间,用于存储局部变量和函数调用信息,这有助于避免线程间的数据干扰。
  • 线程之间可以共享数据:线程共享进程的地址空间,包括全局变量、堆内存等,但需要注意同步机制,以避免数据竞争。
  • 线程的调度由操作系统管理:操作系统负责线程的创建、销毁、切换和调度,线程调度策略包括时间片轮转、优先级调度等。
  1. 线程生命周期

线程的生命周期分为以下几个阶段:

  • 新建(New):创建线程对象时,线程进入新建状态。此时线程尚未分配资源,无法运行。
  • 就绪(Runnable):线程创建成功后,进入就绪状态,等待CPU时间。此时线程已分配资源,可被操作系统调度执行。
  • 运行(Running):线程获得CPU时间,开始执行。线程执行过程中,可能会因为时间片耗尽、等待资源等原因被切换出运行状态。
  • 阻塞(Blocked):线程在等待某个资源或等待其他线程释放锁时进入阻塞状态。线程在阻塞状态时,无法执行指令。
  • 死亡(Terminated):线程执行完毕或被其他线程终止时进入死亡状态。此时线程资源被回收,无法再被调度执行。
  1. 线程优先级

线程优先级决定了线程在调度时的优先级顺序。Java中,线程优先级分为以下等级:

  • MAX_PRIORITY:最高优先级(10):线程优先级最高,优先获得CPU时间。
  • MIN_PRIORITY:最低优先级(1):线程优先级最低,优先级较低。
  • NORM_PRIORITY:默认优先级(5):线程优先级中等。

线程优先级设置需要谨慎,过高或过低的优先级都可能影响系统性能。

  1. 守护线程

守护线程是服务于其他线程的线程,当其他线程结束时,守护线程也会随之结束。Java虚拟机在退出时,如果没有非守护线程正在运行,那么所有守护线程也会随之退出。

守护线程通常用于执行一些不需要用户交互的辅助任务,例如垃圾回收、日志记录等。

  1. 线程池

线程池是一组预先创建的线程,可以复用线程来执行任务。线程池有以下优势:

  • 减少线程创建和销毁的开销:线程池中的线程可以重复使用,避免了频繁创建和销毁线程的开销。
  • 提高系统资源利用率:线程池中的线程可以共享进程资源,提高系统资源利用率。
  • 避免资源竞争:线程池可以限制线程数量,避免资源竞争。

线程池的核心参数配置如下:

  • 核心线程数:线程池中最小的线程数,用于处理任务高峰期。
  • 最大线程数:线程池中最大的线程数,用于处理任务高峰期。
  • 队列容量:工作队列的容量,用于存放等待执行的任务。
  • 拒绝策略:当任务过多,无法被线程池处理时的策略。
  1. 拒绝策略

拒绝策略用于处理当任务过多,无法被线程池处理时的策略。常见的拒绝策略有:

  • AbortPolicy:丢弃任务并抛出异常:当任务无法被处理时,抛出异常,由调用者处理。
  • CallerRunsPolicy:由调用者线程执行任务:当任务无法被处理时,由调用者线程执行任务。
  • DiscardPolicy:丢弃任务,不抛出异常:当任务无法被处理时,直接丢弃任务。
  • DiscardOldestPolicy:丢弃队列中最早的未执行任务:当任务无法被处理时,丢弃队列中最早的未执行任务。
  1. 工作队列类型

线程池的工作队列有以下类型:

  • 阻塞队列(BlockingQueue):线程池中的任务存储在阻塞队列中,当线程池中的线程空闲时,会从队列中获取任务执行。
  • 优先队列(PriorityBlockingQueue):线程池中的任务按照优先级排序,优先级高的任务先执行。
  • 单向队列(LinkedBlockingQueue):线程池中的任务按照先进先出(FIFO)的顺序执行。
  • 双向队列(ArrayBlockingQueue):线程池中的任务按照先进先出(FIFO)的顺序执行,支持指定队列容量。
  1. 同步机制

同步机制用于保证多个线程对共享资源的一致性访问。常见的同步机制有:

  • 锁(Lock):锁是一种同步机制,用于保证多个线程对共享资源的互斥访问。常见的锁有互斥锁、读写锁等。
  • 信号量(Semaphore):信号量是一种同步机制,用于控制对共享资源的访问次数。信号量可以用于实现互斥、同步等。
  • 互斥锁(Mutex):互斥锁是一种同步机制,用于保证多个线程对共享资源的互斥访问。互斥锁通常与条件变量配合使用。
  • 条件变量(Condition):条件变量是一种同步机制,用于在线程间传递条件信息。线程可以在满足条件时进行等待,直到条件成立再继续执行。
  1. 悲观锁/乐观锁

悲观锁假设在访问共享资源时,其他线程会进行修改,因此在访问共享资源时需要加锁。常见的悲观锁有:

  • 乐观锁:在更新共享资源前,判断资源是否被修改过。如果资源未被修改,则进行更新;如果资源已被修改,则放弃更新。
  • 悲观锁:在更新共享资源时,使用锁来保证资源的一致性。悲观锁通常与互斥锁配合使用。
  1. 读写锁

读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。常见的读写锁有:

  • ReentrantReadWriteLock:ReentrantReadWriteLock是一种可重入的读写锁,允许多个线程同时读取共享资源,但写入时需要独占锁。
  • ReadWriteLock:ReadWriteLock是一个读写锁的接口,提供了获取读锁、获取写锁、释放锁等方法。
  1. 条件变量

条件变量用于在线程间传递条件信息。线程可以在满足条件时进行等待,直到条件成立再继续执行。条件变量通常与互斥锁配合使用。

  1. 并发集合

并发集合是专门为并发场景设计的集合类,例如:

  • ConcurrentHashMap:ConcurrentHashMap是Java提供的一个线程安全的哈希表,它采用分段锁机制来提高并发性能。
  • CopyOnWriteArrayList:CopyOnWriteArrayList是一种读写分离的并发容器,它采用复制副本的方式来实现线程安全。
  1. ConcurrentHashMap

ConcurrentHashMap是Java提供的一个线程安全的哈希表,它采用分段锁机制来提高并发性能。ConcurrentHashMap将数据分为多个段,每个段有自己的锁,线程访问不同段的数据时可以并行进行,从而提高并发性能。

  1. CopyOnWrite容器

CopyOnWrite容器是一种读写分离的并发容器,它采用复制副本的方式来实现线程安全。当有线程进行写操作时,CopyOnWrite容器会创建一个新的副本,并在副本上进行修改,修改完成后,将原副本替换为新的副本。这种方式避免了读写操作之间的竞争,提高了并发性能。

  1. BlockingQueue

BlockingQueue是Java提供的一个线程安全的队列,它支持阻塞式操作。当线程尝试向队列中添加元素时,如果队列已满,则线程会等待直到队列有空间;当线程尝试从队列中获取元素时,如果队列为空,则线程会等待直到队列有元素。

  1. 并发工具类

并发工具类包括:

  • Phaser:Phaser是一种用于控制多个线程执行顺序的工具类,它允许线程在执行过程中进行等待和通知。
  • Exchanger:Exchanger是一种用于在线程间交换数据的工具类,它允许两个线程在某个时刻交换数据。
  • FutureTask:FutureTask是一种用于异步执行任务的工具类,它允许线程在执行任务时进行等待和获取结果。
  1. 非阻塞算法

非阻塞算法是指在执行过程中不会阻塞其他线程的算法,例如:

  • CAS(Compare and Swap)算法:CAS算法是一种无锁并发控制算法,它通过比较和交换操作来实现线程之间的数据同步。
  • Atomic类:Atomic类提供了一系列线程安全的原子操作,例如AtomicInteger、AtomicLong、AtomicReference等。
  • 无锁队列:无锁队列是一种线程安全的队列,它采用CAS算法来实现线程安全。
  1. CAS原理

CAS算法是一种无锁并发控制算法,它通过比较和交换操作来实现线程之间的数据同步。CAS算法包含三个操作数:内存位置V、预期值A和新值B。当内存位置V的值与预期值A相等时,将内存位置V的值修改为新值B,否则不做任何操作。

  1. Atomic类

Atomic类提供了一系列线程安全的原子操作,例如:

  • AtomicInteger:AtomicInteger是一种线程安全的整型变量,它提供了原子操作方法,例如getAndIncrement、compareAndSet等。
  • AtomicLong:AtomicLong是一种线程安全的长整型变量,它提供了原子操作方法,例如getAndAdd、compareAndSet等。
  • AtomicReference:AtomicReference是一种线程安全的引用变量,它提供了原子操作方法,例如getAndSet、compareAndSet等。
  1. 无锁队列

无锁队列是一种线程安全的队列,它采用CAS算法来实现线程安全。无锁队列中的元素存储在数组中,线程在添加或删除元素时,会使用CAS算法来保证操作的原子性。

  1. 并发框架

并发框架包括:

  • Netty:Netty是一个基于NIO的异步事件驱动的网络框架,它提供了高性能、可扩展的网络通信解决方案。
  • Akka:Akka是一个用于构建高并发、分布式和容错应用程序的框架,它基于actor模型,提供了强大的并发编程能力。
  • Disruptor:Disruptor是一个高性能的环形缓冲区框架,它采用无锁设计,提供了高性能的并发编程解决方案。

二、MyBatis知识体系

MyBatis是一个流行的持久层框架,它可以将SQL映射成Java代码,简化了数据库操作。以下是MyBatis的一些基础知识点及其技术实现细节:

  1. SQL映射

SQL映射是将数据库表中的字段与Java对象的属性进行映射的过程。MyBatis支持以下SQL映射方式:

  • XML映射:通过XML文件定义SQL映射,将SQL语句与Java对象进行映射。
  • 注解映射:通过在Java接口或实体类上使用注解来实现SQL映射。
  1. 注解映射

注解映射是通过在Java接口或实体类上使用注解来实现SQL映射。常见的注解有:

  • @Select:用于定义查询SQL语句。
  • @Insert:用于定义插入SQL语句。
  • @Update:用于定义更新SQL语句。
  • @Delete:用于定义删除SQL语句。
  • @Result:用于定义结果集映射。
  • @Results:用于定义多个结果集映射。
  • @One:用于定义一对一关系。
  • @Many:用于定义一对多关系。
  1. 结果集映射

结果集映射是将数据库查询结果映射到Java对象的过程。MyBatis支持以下结果集映射方式:

  • 类型处理器:类型处理器用于将数据库中的数据类型转换为Java对象中的数据类型。
  • 结果集映射配置:通过XML或注解配置结果集映射,将数据库字段与Java对象的属性进行映射。
  1. 关联查询

关联查询用于查询多表之间的关系,例如:

  • 一对一:通过@One注解定义一对一关系,MyBatis会自动执行关联查询。
  • 一对多:通过@Many注解定义一对多关系,MyBatis会自动执行关联查询。
  • 多对多:通过@Many注解定义多对多关系,MyBatis会自动执行关联查询。
  1. 动态SQL

动态SQL允许根据不同的条件动态生成SQL语句。MyBatis支持以下动态SQL方式:

  • OGNL表达式:OGNL表达式用于动态生成SQL语句,例如根据条件动态拼接SQL片段。
  • 分支语句:分支语句用于根据条件动态选择不同的SQL语句。
  • 批量操作:批量操作用于同时执行多个SQL语句,提高数据库操作效率。
  1. 缓存机制

MyBatis提供了两种缓存机制:

  • 一级缓存:本地缓存,每个线程拥有独立的缓存区域。一级缓存的作用是减少数据库访问次数,提高查询效率。
  • 二级缓存:全局缓存,所有线程共享同一个缓存区域。二级缓存的作用是跨线程共享数据,提高查询效率。
  1. 自定义缓存

自定义缓存允许开发者自定义缓存策略。在MyBatis中,可以通过实现Cache接口来实现自定义缓存。自定义缓存可以用于实现更复杂的缓存策略,例如缓存数据过期、缓存数据淘汰等。

  1. 代理模式

MyBatis使用代理模式来实现延迟加载和动态代理。通过代理模式,可以在不修改原始对象的情况下,动态添加或修改对象的行为。

  1. MapperProxy

MapperProxy是MyBatis中用于实现动态代理的类。MapperProxy负责拦截对Mapper接口的调用,并将调用转换为对应的SQL语句执行。

  1. 插件拦截

MyBatis允许通过插件来拦截SQL执行过程。常见的插件有:

  • Executor插件:拦截SQL执行过程,例如执行SQL前、执行SQL后等。
  • ResultHandler插件:拦截结果集处理过程,例如结果集转换、结果集映射等。
  1. 动态代理执行流程

动态代理的执行流程如下:

  • 创建动态代理对象:通过Proxy类创建动态代理对象,代理对象实现了Mapper接口。
  • 调用代理对象的方法:调用代理对象的方法时,会触发代理模式的拦截器链。
  • 拦截器链调用:拦截器链按照定义的顺序执行,拦截器可以修改方法调用、执行额外操作等。
  • 执行原始方法:拦截器链执行完成后,执行原始方法,即执行对应的SQL语句。
  • 返回结果:将执行结果返回给调用者。
  1. SqlSession生命周期

SqlSession是MyBatis中用于操作数据库的接口,它具有以下生命周期:

  • 创建SqlSession对象:通过SqlSessionFactory创建SqlSession对象,用于执行数据库操作。
  • 使用SqlSession对象执行数据库操作:通过SqlSession对象执行数据库操作,例如查询、插入、更新、删除等。
  • 关闭SqlSession对象:关闭SqlSession对象,释放数据库连接资源。
  1. 执行器类型

MyBatis提供了以下执行器类型:

  • SimpleExecutor:简单执行器,直接执行SQL语句。SimpleExecutor适用于简单场景,性能较低。
  • ReuseExecutor:重用预处理语句执行器,提高SQL执行效率。ReuseExecutor通过重用预处理语句来提高SQL执行效率。
  • BatchExecutor:批量执行器,将多个SQL语句合并为一个批量执行。BatchExecutor适用于批量操作,提高数据库操作效率。
  1. 延迟加载

延迟加载是指在需要时才加载数据的策略,可以提高应用程序的响应速度。延迟加载可以减少初始加载时间,提高应用程序的性能。

  1. 扩展机制

MyBatis提供了以下扩展机制:

  • 类型处理器:类型处理器用于将数据库中的数据类型转换为Java对象中的数据类型。
  • 拦截器链:拦截器链用于拦截SQL执行过程,例如执行SQL前、执行SQL后等。
  • 方言支持:方言支持是指MyBatis支持不同数据库的SQL语法,例如MySQL方言、Oracle方言、SQL Server方言等。
  1. 类型处理器

类型处理器用于将数据库中的数据类型转换为Java对象中的数据类型。类型处理器可以通过实现TypeHandler接口来实现。

  1. 拦截器链

拦截器链用于拦截SQL执行过程,例如:

  • SQL执行拦截:拦截器可以修改SQL语句、执行额外操作等。
  • 结果集处理拦截:拦截器可以修改结果集、执行额外操作等。
  1. 方言支持

方言支持是指MyBatis支持不同数据库的SQL语法,例如:

  • MySQL方言:支持MySQL数据库的SQL语法。
  • Oracle方言:支持Oracle数据库的SQL语法。
  • SQL Server方言:支持SQL Server数据库的SQL语法。

通过以上知识点,我们可以了解到并发编程和MyBatis的相关概念和技术。在实际应用中,我们需要根据具体场景选择合适的并发编程模型和MyBatis配置,以提高应用程序的性能和可维护性。

CSDN

📥博主的人生感悟和目标

Java程序员廖志伟

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

- 💂 博客主页Java程序员廖志伟
- 👉 开源项目Java程序员廖志伟
- 🌥 哔哩哔哩Java程序员廖志伟
- 🎏 个人社区Java程序员廖志伟
- 🔖 个人微信号SeniorRD

Java程序员廖志伟

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

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值