jedis是什么,为什么是线程不安全的

常用的操作redis的客户端工具

jedis

Jedis 是 Redis 官方推荐的 Java 连接开发工具,jedis非线程安全。

但是可以通过JedisPool连接池去管理实例,在多线程情况下让每个线程有自己独立的jedis实例,可变为线程安全。

Lettuce

Lettuce 是基于 Netty框架(NIO)的事件驱动的通信,支持同步和异步调用的,可扩展的 redis client,多个线程可以共享一个 RedisConnection,线程安全。

SpringBoot2.0之后默认都是使用的Lettuce这个客户端连接Redis服务器。Lettuce 是一种可扩展的、线程安全的 Redis 高级客户端。

Redisson

Redisson 是一个在 Redis 的功能基础上实现的 Java 驻内存数据网格客户端。实现了分布式和可扩展的 Java 数据结构,提供很多分布式相关操作服务,例如分布式锁,分布式集合,可通过 Redis 支持延迟队列。

小结

Jedis 和 Lettuce 两者相比,Jedis 的性能比较差,其他方面并没有太明显的区别,所以如果你不需要使用 Redis 的高级功能的话,优先推荐使用 Lettuce。

相比于 Jedis、Lettuce 等基于 redis 命令封装的客户端,Redisson 提供的功能更加高端和抽象,逼格简单使用

jedis和lettuce简单使用:https://juejin.cn/post/6844903681087930375,文章中的使用用lettuce时,需添加commons-pool2依赖。

jedis线程不安全

以set方法举例

Jedis jedis = new Jedis();
jedis.set("1","1");

1、

一步步点进去Jedis.set->Client.set->BinaryClient.set->Connection.sendCommand

可以看出来 每次执行set方法都要进行connect方法,点进connect方法

可以看出来一个实例共用一个socket、 outputStream、inputStream。问题也就出现了。来看下jedisSocketFactory.createSocket的方法

问题解说:这样就清晰明了了,共用socket,在多线程执行下,如果线程2走到了获取outputStream或者inputStream的方法,而线程1走到了刚刚new完socket,是不是就出现问题了。

 2、

眼尖的人可能会看到

 如果我提前连接比如以下,是不是不会出问题了,并不是

        Jedis jedis = new Jedis();
        jedis.connect();
        jedis.set("1","1");

 别忘了还共享了 outputStream、inputStream。我们直接来到发送命令的最后Protocol的sendCommand方法

 问题解说:因为共享了os,使得线程1正在正常发送指令,线程2突然插入一脚,让发送到服务端的指令不能被服务端识别,所以还可能出现连接断开等问题。

总结

不总结了,自己看吧。着急下班。

猜你喜欢

转载自blog.csdn.net/wai_58934/article/details/128649058
今日推荐