并发编程核心知识

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

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

Java程序员廖志伟

💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

优快云

一、并发编程知识体系

并发编程是计算机科学中的一个关键领域,它探讨了如何高效地让计算机系统在同一时刻执行多个任务。以下是针对并发编程知识体系的多角度详细阐述,包含技术实现细节。

  1. 线程基础

线程是并发编程中的基本执行单元,是操作系统进行任务调度的最小执行单位。线程的特点包括:

(1)独立调度:操作系统可以独立调度线程执行,线程可以并发运行。

(2)资源共享:线程可以共享进程的资源,如内存空间、文件句柄等。

(3)切换开销:线程切换需要一定的系统开销,频繁切换会影响系统性能。

  1. 线程生命周期

线程的生命周期经历了多个阶段,每个阶段都有其特定的技术实现:

(1)新建(New):线程对象被创建,此时线程资源未被分配。

(2)就绪(Runnable):线程创建后,调用start()方法进入就绪状态,等待CPU调度。调度器在合适的时机将线程状态转换为运行状态。

(3)运行(Running):CPU调度器选中线程进行执行,此时线程处于运行状态。线程执行期间,可能会因为I/O操作、等待锁等原因导致状态转换。

(4)阻塞(Blocked):线程由于等待某些资源或等待某个事件发生而无法继续执行。线程在等待过程中,其状态由运行转换为阻塞。

(5)等待(Waiting):线程主动进入等待状态,需要其他线程显式唤醒。例如,线程通过调用wait()方法进入等待状态。

(6)超时等待(Timed Waiting):线程在等待一段时间后自动进入就绪状态。线程通过调用sleep()方法进行超时等待。

(7)终止(Terminated):线程执行完毕或被强制终止后,进入终止状态。此时线程资源将被回收。

  1. 线程优先级

线程优先级决定了线程在CPU调度时的优先级,优先级高的线程更有可能获得CPU时间。线程优先级的实现依赖于操作系统的调度算法:

(1)最低优先级:线程优先级最低,几乎不会被CPU调度。

(2)正常优先级:线程优先级一般,介于最低和最高优先级之间。

(3)最高优先级:线程优先级最高,更容易获得CPU时间。

  1. 守护线程

守护线程是一种特殊的线程,它服务于应用程序,当所有非守护线程结束时,守护线程也会自动结束。守护线程主要用于以下场景:

(1)后台服务:如垃圾回收器、日志记录器等。

(2)资源清理:如关闭文件、释放资源等。

  1. 线程池

线程池是一种管理线程的机制,它可以减少线程创建和销毁的开销,提高系统性能。线程池的实现涉及以下几个方面:

(1)工作线程:执行实际任务的线程。

(2)阻塞队列:存储等待执行的任务。

(3)拒绝策略:当线程池无法处理更多任务时,拒绝策略决定如何处理新任务。例如,拒绝策略可以抛出异常、丢弃任务等。

  1. 核心参数配置

线程池的核心参数配置包括:

(1)核心线程数:线程池在运行过程中,能够保持的最小线程数。

(2)最大线程数:线程池在运行过程中,能够保持的最大线程数。

(3)存活时间:空闲线程在终止前能够保持的最大时间。

(4)阻塞队列容量:阻塞队列能够存储的最大任务数。

  1. 拒绝策略

拒绝策略用于处理线程池无法处理更多任务的情况,常见的拒绝策略包括:

(1)AbortPolicy:抛出RejectedExecutionException异常。

(2)CallerRunsPolicy:调用任务的线程处理该任务。

(3)DiscardPolicy:忽略该任务。

(4)DiscardOldestPolicy:丢弃队列中最早的任务,再尝试执行当前任务。

  1. 工作队列类型

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

(1)LinkedBlockingQueue:基于链表的阻塞队列,支持有界和无界队列。

(2)ArrayBlockingQueue:基于数组的阻塞队列,支持有界队列。

(3)PriorityBlockingQueue:具有优先级的阻塞队列,元素按照优先级排序。

(4)SynchronousQueue:不存储元素的阻塞队列,生产者和消费者线程必须交替执行。

  1. 同步机制

同步机制用于解决多线程并发访问共享资源时可能出现的数据不一致问题。常见的同步机制包括:

(1)互斥锁(Mutex):保证同一时间只有一个线程访问共享资源。互斥锁的实现通常采用自旋锁、轮询锁等策略。

(2)读写锁(RWLock):允许多个线程同时读取共享资源,但写入时需要独占访问。读写锁的实现通常采用读写标记、读写计数器等策略。

(3)条件变量(Condition):允许线程在满足特定条件时等待,并在条件满足时被唤醒。条件变量的实现通常采用条件队列、等待/通知机制等策略。

  1. 悲观锁/乐观锁

悲观锁和乐观锁是解决并发数据一致性问题的一种方法。悲观锁的实现通常采用锁机制,乐观锁的实现通常采用版本号或时间戳等策略。

(1)悲观锁:假设并发访问时,数据一定会发生冲突,因此在访问数据前先加锁,确保数据的一致性。

(2)乐观锁:假设并发访问时,数据不会发生冲突,因此在访问数据时不加锁,而是在更新数据时检查版本号或时间戳,确保数据的一致性。

  1. 读写锁

读写锁是一种允许多个线程同时读取共享资源,但写入时需要独占访问的锁。读写锁的实现通常采用读写标记、读写计数器等策略。

(1)读锁:允许多个线程同时获取读锁,但不会获取写锁。

(2)写锁:允许多个线程获取写锁,但不会获取读锁。

  1. 条件变量

条件变量是一种线程间通信的机制,它允许线程在满足特定条件时等待,并在条件满足时被唤醒。条件变量的实现通常采用条件队列、等待/通知机制等策略。

  1. 并发集合

并发集合是在多线程环境下,能够保证数据一致性的集合类。常见的并发集合包括:

(1)ConcurrentHashMap:线程安全的HashMap,采用分段锁技术。

(2)CopyOnWriteArrayList:线程安全的ArrayList,在添加或删除元素时,会创建新的副本。

  1. ConcurrentHashMap

ConcurrentHashMap是一种线程安全的HashMap,它采用分段锁技术,提高并发性能。分段锁技术将数据结构划分为多个段,每个段由一个锁保护。

  1. CopyOnWrite容器

CopyOnWrite容器是一种线程安全的容器,它在添加或删除元素时,会创建新的副本。CopyOnWrite容器适用于读多写少的应用场景。

  1. BlockingQueue

BlockingQueue是一种阻塞队列,它允许生产者和消费者线程在没有数据或空间时等待。BlockingQueue的实现通常采用锁机制,确保线程安全。

  1. 并发工具类

并发工具类包括CountDownLatch、Semaphore、CyclicBarrier等,用于实现线程间的同步和协作。这些工具类的实现通常基于锁机制、条件变量等策略。

  1. Phaser

Phaser是一种可重用的同步屏障,它允许线程在执行特定操作前等待其他线程。Phaser的实现通常采用条件变量、锁机制等策略。

  1. Exchanger

Exchanger是一种线程间交换数据的机制,它允许两个线程在执行特定操作前交换数据。Exchanger的实现通常采用锁机制、条件变量等策略。

  1. FutureTask

FutureTask是一种可以异步执行任务的线程,它允许调用者获取执行结果。FutureTask的实现通常采用线程池、任务队列等策略。

  1. 非阻塞算法

非阻塞算法是一种在多线程环境下,不使用锁或其他同步机制,实现线程安全的方法。非阻塞算法的实现通常采用原子操作、条件变量等策略。

  1. CAS原理

CAS(Compare-And-Swap)是一种无锁算法,它通过比较内存中的值和期望值,如果相等则将内存中的值更新为新值。CAS的实现通常采用硬件指令、原子操作等策略。

  1. Atomic类

Atomic类提供了一系列原子操作,用于实现线程安全的操作。Atomic类的实现通常采用原子操作、锁机制等策略。

  1. 无锁队列

无锁队列是一种在多线程环境下,不使用锁或其他同步机制,实现线程安全的数据结构。无锁队列的实现通常采用CAS原理、原子操作等策略。

  1. 并发框架

并发框架是一种提供并发编程工具和机制的库,如Netty、Akka、Disruptor等。并发框架的实现通常采用线程池、任务队列、锁机制等策略。

  1. Netty线程模型

Netty采用主从多线程模型,主线程负责接收客户端连接,从线程负责处理业务逻辑。Netty线程模型的实现通常采用线程池、任务队列等策略。

  1. Akka Actor模型

Akka采用Actor模型,将系统分解为多个Actor,每个Actor独立运行,并通过消息传递进行通信。Akka Actor模型的实现通常采用消息队列、锁机制等策略。

  1. Disruptor环形缓冲区

Disruptor采用环形缓冲区,它通过环形队列的方式存储数据,提高并发性能。Disruptor环形缓冲区的实现通常采用原子操作、锁机制等策略。

二、MyBatis知识体系

MyBatis是一款优秀的持久层框架,它将数据库操作封装成Java对象,简化了数据库开发。以下是针对MyBatis知识体系的多角度详细阐述,包含技术实现细节。

  1. SQL映射

SQL映射是MyBatis的核心概念,它将Java对象与数据库表进行映射。SQL映射的实现涉及以下几个方面:

(1)实体类:对应数据库表中的记录。实体类的属性与数据库表中的列进行映射。

(2)映射文件:定义SQL语句和Java对象之间的映射关系。映射文件可以使用XML或注解的方式定义。

  1. 注解映射

注解映射是MyBatis提供的一种简单易用的映射方式,它通过注解直接在Java对象上定义映射关系。注解映射的实现通常采用反射、注解处理器等策略。

  1. 结果集映射

结果集映射是将SQL查询结果映射到Java对象的过程。结果集映射的实现涉及以下几个方面:

(1)单列映射:将查询结果中的一列映射到Java对象的属性。

(2)多列映射:将查询结果中的多列映射到Java对象的多个属性。

  1. 关联查询

关联查询用于实现多表之间的关联操作。关联查询的实现涉及以下几个方面:

(1)一对一:一个实体类对应一个关联实体类。一对一关联的实现通常采用嵌套查询或联合查询。

(2)一对多:一个实体类对应多个关联实体类。一对多关联的实现通常采用嵌套查询或联合查询。

(3)多对多:多个实体类之间存在多对多关系。多对多关联的实现通常采用关联表或中间表。

  1. 动态SQL

动态SQL允许在运行时根据条件动态构建SQL语句。动态SQL的实现涉及以下几个方面:

(1) :根据条件判断是否执行SQL片段。

(2) :根据条件判断执行不同的SQL片段。

(3) :遍历集合,生成SQL片段。

  1. OGNL表达式

OGNL表达式用于在MyBatis中获取Java对象的属性值。OGNL表达式的实现通常采用反射、表达式解析器等策略。

  1. 分支语句

分支语句用于在MyBatis中实现条件分支。分支语句的实现通常采用条件判断、标签等策略。

  1. 批量操作

批量操作允许一次性执行多条SQL语句。批量操作的实现通常采用批处理技术、执行器等策略。

  1. 缓存机制

MyBatis提供了一级缓存和二级缓存机制,用于提高数据库查询性能。缓存机制的实现涉及以下几个方面:

(1)一级缓存:会话级别的缓存,仅对当前会话有效。一级缓存通常采用HashMap实现。

(2)二级缓存:全局级别的缓存,对所有会话有效。二级缓存通常采用HashMap实现,并通过namespace进行隔离。

  1. 自定义缓存

自定义缓存允许用户根据需求自定义缓存实现。自定义缓存的实现通常采用缓存接口、缓存实现类等策略。

  1. 代理模式

代理模式用于实现MyBatis的动态代理,将接口方法转换为SQL执行。代理模式的实现通常采用Java动态代理技术。

  1. MapperProxy

MapperProxy是MyBatis的动态代理实现,它负责执行SQL语句。MapperProxy的实现通常采用反射、代理模式等策略。

  1. 插件拦截

插件拦截允许用户在MyBatis执行过程中插入自定义逻辑。插件拦截的实现通常采用代理模式、拦截器等策略。

  1. 动态代理执行流程

动态代理执行流程包括以下步骤:

(1)代理类加载:加载动态代理类。

(2)代理对象创建:创建代理对象。

(3)方法执行:代理对象执行方法,拦截器链处理。

  1. SqlSession生命周期

SqlSession是MyBatis的核心接口,它负责执行SQL语句、管理事务等。SqlSession的生命周期包括以下阶段:

(1)创建SqlSession:通过SqlSessionFactory创建SqlSession。

(2)执行SQL语句:使用SqlSession执行SQL语句。

(3)关闭SqlSession:关闭SqlSession,释放资源。

  1. 执行器类型

MyBatis提供多种执行器类型,包括简单执行器、批量执行器等。执行器类型的实现通常采用批处理技术、执行器等策略。

  1. 延迟加载

延迟加载是指在需要时才加载资源,提高系统性能。延迟加载的实现通常采用代理模式、懒加载等策略。

  1. 扩展机制

MyBatis提供扩展机制,允许用户自定义插件、拦截器等。扩展机制的实现通常采用插件机制、拦截器等策略。

  1. 类型处理器

类型处理器用于将数据库类型转换为Java类型。类型处理器的实现通常采用反射、类型转换器等策略。

  1. 拦截器链

拦截器链用于在MyBatis执行过程中插入自定义逻辑。拦截器链的实现通常采用拦截器、链式调用等策略。

  1. 方言支持

方言支持允许MyBatis根据数据库类型自动选择合适的SQL语句。方言支持的实现通常采用字符串匹配、映射器等策略。

通过以上对并发编程和MyBatis知识体系的详细介绍,我们可以更好地理解和应用这些技术。在实际开发中,我们可以根据需求选择合适的并发编程技术和MyBatis配置,提高系统性能和开发效率。

优快云

博主分享

📥博主的人生感悟和目标

Java程序员廖志伟

📙经过多年在优快云创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。

面试备战资料

八股文备战
场景描述链接
时间充裕(25万字)Java知识点大全(高频面试题)Java知识点大全
时间紧急(15万字)Java高级开发高频面试题Java高级开发高频面试题

理论知识专题(图文并茂,字数过万)

技术栈链接
RocketMQRocketMQ详解
KafkaKafka详解
RabbitMQRabbitMQ详解
MongoDBMongoDB详解
ElasticSearchElasticSearch详解
ZookeeperZookeeper详解
RedisRedis详解
MySQLMySQL详解
JVMJVM详解

集群部署(图文并茂,字数过万)

技术栈部署架构链接
MySQL使用Docker-Compose部署MySQL一主二从半同步复制高可用MHA集群Docker-Compose部署教程
Redis三主三从集群(三种方式部署/18个节点的Redis Cluster模式)三种部署方式教程
RocketMQDLedger高可用集群(9节点)部署指南
Nacos+Nginx集群+负载均衡(9节点)Docker部署方案
Kubernetes容器编排安装最全安装教程

开源项目分享

项目名称链接地址
高并发红包雨项目https://gitee.com/java_wxid/red-packet-rain
微服务技术集成demo项目https://gitee.com/java_wxid/java_wxid

管理经验

【公司管理与研发流程优化】针对研发流程、需求管理、沟通协作、文档建设、绩效考核等问题的综合解决方案:https://download.youkuaiyun.com/download/java_wxid/91148718

希望各位读者朋友能够多多支持!

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

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值