news 2026/5/12 23:12:20

Jedis线程不安全问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jedis线程不安全问题

1. 为什么 Jedis 是线程不安全的?

Jedis 实例在多线程环境下是线程不安全的。其根本原因在于 Jedis 的底层实现:

  • 共享 Socket 连接:Jedis 内部维护了一个唯一的Socket连接和对应的输入/输出流(InputStream/OutputStream)。
  • 请求-响应模式冲突:Jedis 发送请求和接收响应是串行的。如果多个线程共享同一个 Jedis 实例,线程 A 发送了GET key1,在读取响应前,线程 B 发送了SET key2 val2。此时线程 A 读取到的响应可能是线程 B 操作的结果,从而导致数据错乱协议解析异常Socket 连接关闭

2. 解决方案:JedisPool (线程池)

为了解决线程安全问题并提高性能,官方推荐使用JedisPool

  • 原理:预先创建一组 Jedis 实例并存入池中。每个线程需要操作 Redis 时,从池中“借出”一个专用的实例,操作完成后再“归还”。
  • 效果:确保在同一时刻,一个 Jedis 实例只被一个线程独占,从物理上隔离了线程竞争。

3. 代码示例

A. 依赖配置 (Maven)

pom.xml中引入 Jedis 和连接池依赖(适配 Spring Boot 3.4.2 开发环境):

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.12.0</version></dependency>

B. JedisPool 初始化配置

配置线程池的核心参数,以保证高并发下的稳定性:

publicclassJedisPoolFactory{privatestaticfinalJedisPooljedisPool;static{// 1. 配置连接池参数JedisPoolConfigconfig=newJedisPoolConfig();config.setMaxTotal(20);// 最大连接数config.setMaxIdle(10);// 最大空闲连接config.setMinIdle(2);// 最小空闲连接config.setMaxWait(Duration.ofMillis(2000));// 获取连接最大等待时间// 2. 初始化 JedisPooljedisPool=newJedisPool(config,"127.0.0.1",6379,1000,"your_password");}publicstaticJedisgetJedis(){returnjedisPool.getResource();}}

C. 正确的使用模式 (Try-with-resources)

使用try-with-resources语法可以确保 Jedis 实例在使用完毕后自动触发close()方法归还给线程池,而不是关闭 Socket:

publicvoidredisOperation(){// 从池中借出连接try(Jedisjedis=JedisPoolFactory.getJedis()){// 执行 Redis 命令jedis.set("user:name","czl");// 示例使用Stringvalue=jedis.get("user:name");System.out.println("Result: "+value);}catch(Exceptione){// 异常处理逻辑e.printStackTrace();}// 退出 try 块后,jedis 实例自动归还到线程池}

4. 在 SpringBoot 中集成 Jedis 线程池

在 Spring Boot 项目中,我们不再需要手动通过JedisPool编写工厂类,而是利用Spring Data Redis提供的自动化配置。

4.1 核心依赖配置

首先,在pom.xml中引入spring-boot-starter-data-redis。 注意必须显式排除默认的 Lettuce 客户端(Spring Boot 默认使用 Lettuce),并引入 Jedis 驱动:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>

4.2 YAML 线程池参数配置

application.yaml中,我们需要指定客户端类型为jedis,并配置具体的连接池参数以确保多线程安全。

spring:data:redis:host:127.0.0.1port:6379client-type:jedis# 指定使用 Jedis 客户端jedis:pool:max-active:20# 连接池最大连接数(对应 maxTotal)max-idle:10# 最大空闲连接min-idle:2# 最小空闲连接max-wait:2000ms# 获取连接的最大等待时间

5. 代码实现示例

5.1 自定义序列化配置

为了配合你之前使用的JsonUtils,建议配置一个自定义的RedisTemplate。 Spring 会自动将上述 YAML 中的连接池参数注入到RedisConnectionFactory中。

@ConfigurationpublicclassRedisConfig{@BeanpublicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=newRedisTemplate<>();template.setConnectionFactory(factory);// 使用 String 序列化 Keytemplate.setKeySerializer(newStringRedisSerializer());// 使用 JSON 序列化 Valuetemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());returntemplate;}}

5.2 业务调用示例

在业务层,直接注入RedisTemplate。 Spring Data Redis 会自动从池中借还连接,你无需再关心close()JedisPool的手动操作:

@ServicepublicclassUserService{@AutowiredprivateRedisTemplate<String,Object>redisTemplate;publicvoidsaveUser(UserDOuser){// 底层自动从 JedisPool 借出连接,执行完自动归还redisTemplate.opsForValue().set("user:"+user.getId(),user);}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 15:31:22

2026年AI大模型彻底爆发,从入门到高薪,一篇搞定

AI大模型迎来爆发式增长&#xff0c;岗位需求激增543%&#xff0c;高薪岗位涌现。自学面临资源零散、缺乏指导、跟不上发展速度三大困境。专业培训提供系统化内容、及时反馈和实战项目&#xff0c;是快速掌握AI技能的最优路径。未来职场趋势是"AI岗位"模式&#xff0…

作者头像 李华
网站建设 2026/5/9 23:00:27

解锁周庄:从双桥到沈厅,读懂枕水江南的精髓

周庄&#xff0c;位于江苏省昆山市西南部&#xff0c;是一座四面环水、由澄湖、淀山湖、南湖等湖泊环抱的“岛中之镇”。这座古镇始于北宋时期&#xff0c;至今已有九百余年历史&#xff0c;以保存完好的明清建筑群落、纵横交错的“井”字形河道体系和“小桥、流水、人家”的典…

作者头像 李华
网站建设 2026/5/1 10:20:45

破解大模型交付困境:从“烧钱“到“赚钱“的转型指南

大模型交付面临成本与收益倒挂困境&#xff1a;高固定成本与线性收入模式不匹配。解决方案是从"项目制"转型为"产品化"模式&#xff0c;通过构建"资产漏斗"将交付转化为资产沉淀&#xff0c;降低边际成本&#xff0c;提升价值溢价。同时需改变与…

作者头像 李华
网站建设 2026/5/11 19:06:47

小白/程序员如何成功转型大模型行业?全方位指南与岗位解析

本文探讨了进入AI行业的路径选择&#xff0c;针对不同背景人群提出建议&#xff1a;非技术背景者可考虑AI产品、运营、分析等岗位&#xff1b;刚毕业学生可根据风险偏好选择杭州(新兴AI企业)或清华(学术氛围)&#xff1b;转行需培养AI理解能力和项目思维&#xff0c;建议先工作…

作者头像 李华
网站建设 2026/5/11 6:48:13

大模型时代AI产品岗招聘火爆:零基础小白如何1-2个月快速上岸?2026年从被裁员到涨薪转行到AI圈,我是怎么做到的?

文章介绍AI产品岗位招聘火爆情况&#xff0c;强调12月是转行AI的最佳启动点&#xff0c;可避开竞争高峰。详细列举2026年AI高薪岗位TOP4&#xff0c;展示多个成功转行案例。课程专为土建背景人士设计&#xff0c;通过系统学习和实战项目&#xff0c;帮助学员在2-4个月内完成转行…

作者头像 李华