zoukankan      html  css  js  c++  java
  • 关于Jedis是否线程安全的测试

    转:

    关于Jedis是否线程安全的测试

    版权声明:转载请注明出处 https://blog.csdn.net/jk940438163/article/details/82787446

    由于最近项目需要引入Redis用作缓存管理,所以开始了对Redis的学习。自学还算顺利,但到了java接入的时候,看到jedis的链接池,就产生了疑问:明明server端对数据的读写时单线程,为什么还要用链接池呢?

    经过一轮的百度,得知这里面有两个原因:

    ①主要原因:redis的性能瓶颈主要时网络通讯——网络通讯速度比redis处理速度要慢许多。单客户端会导致,网络通讯的时间里,redis处于闲暇,无法发挥其处理能力;

    ②不那么主要(个人认为也很主要)原因:jedis非线程安全。但是百度到的帖子和博客,均没有给出靠谱的测试程序去证明这个说法。

    于是乎就自己试着写一个简单的测试程序去求证,结果感人~下面上测试代码和运行结果:

    先说结论吧:jedis确实是非线程安全的。

    代码:

    public class Test {
         
        public static void main(String[] args) {
            //连接本地的 Redis 服务
            Jedis jedis = new Jedis("localhost");
            //查看服务是否运行
            System.out.println("服务正在运行: "+jedis.ping());
     
            for (int i = 0; i < 2; i++) {
                int finalI = i;
                new Thread(() -> {
                    for (int j = 0; j < 10; j++) {
                        jedis.set("a" + finalI, String.valueOf(finalI));
                        System.out.println("a" + finalI + " = " + jedis.get("a" + finalI));
                    }
                }).start();
            }
        }
    }

    结果:

    1. 服务正在运行: PONG
    2. a1 = OK
    3. a1 = OK
    4. a0 = 1
    5. a0 = OK
    6. a1 = 1
    7. a1 = OK
    8. a1 = 1
    9. a0 = OK
    10. a0 = OK
    11. a1 = 0
    12. a1 = OK
    13. a0 = 0
    14. a0 = 1
    15. a1 = OK
    16. a1 = OK
    17. a0 = 1
    18. a1 = OK
    19. a0 = 1
    20. a0 = OK
    21. a0 = OK

    解析说明:

    假设jedis是线程安全的,那么在代码中,输出语句:“System.out.println("a" + finalI + " = " + jedis.get("a" + finalI));”的预期输出结果应该是“a0 = 0”或“a1 = 1”。但是实际上控制台中可以看到“a0 = OK”、“a0 = 1”这样神奇的输出。

    然后会出现这样输出的具体原因是什么呢——可以看这里:jedis源码分析及jedis实例非线程安全分析(PS:遗憾没联系上博主,侵删。无论如何,感谢该博主的付出)。大概意思就是,jedis的请求流和响应流都是全局变量,当不同的线程在set和get的时候,有可能会出现线程A的set()的响应流,被线程B的get()作为返回了,所以出现了“a0 = OK”的情况。“a0 = 1”同理:线程A的get("a1")的响应流被线程B的get("a0")返回了。

     

    结尾:

    测试代码在后续的使用时偶尔会报异常,不能正常跑。小弟能力有限,在此就不深究了,希望有大牛能评论说明一下原因吧~

    之前没写过写博客,这是第一次,写得不好的话,请见谅。 另外,转载请指明出处~

  • 相关阅读:
    升级Nginx1.14.1以上版本
    MaxScale中间件部署数据库读写分离
    php文件锁解决少量并发问题
    使用mysql悲观锁解决并发问题
    配置和查看composer镜像
    PHP常用的 五种设计模式及应用场景
    全球免费公共 DNS 解析服务器 IP 地址列表推荐 (解决无法上网/加速/防劫持)
    九种跨域方式实现原理
    Hadoop中RPC协议小例子报错java.lang.reflect.UndeclaredThrowableException解决方法
    DataNode启动不成功——java.net.BindException: Port in use: localhost:0 Caused by: java.net.BindException: Cannot assign requested address解决办法
  • 原文地址:https://www.cnblogs.com/libin6505/p/10697371.html
Copyright © 2011-2022 走看看