zoukankan      html  css  js  c++  java
  • Redis本身是单线程线程安全的内存数据库,但是不代表你的使用就是线程安全的

    网上一个错误示例:https://www.cnblogs.com/Simeonwu/p/7881100.html,部分代码如下:

    package com.me.config;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    /**
     * Project: me
     * Package: com.me.config
     * Date: 2017/11/22 19:30
     * Author: Simeon
     */
    
    class Demo extends Thread
    {
        public void run()
        {
            Jedis jedis1 = new Jedis();
            for (int i=0;i<100;i++){
                int num = Integer.parseInt(jedis1.get("num"));// 1: 代码行1
                num = num + 1; // 2: 代码行2
                jedis1.set("num",num+"");
                System.out.println(jedis1.get("num"));
            }
        }
    
    }
    
    public class test{
    
        public static void main(String... args){
            Jedis jedis = new Jedis();
            jedis.set("num","1");
            new Demo().start();
            new Demo().start();
        }
    
    }

    如代码所示,例如当线程1在代码行读取数值为99时候,此时线程2页执行读取操作也是99,随后同时执行num=num+1,之后更新,导致一次更新丢失,这就是这个代码测试的错误之处。所以Redis本身是线程安全的,但是你还需要保证你的业务必须也是线程安全的。

    注意:千万不要以为原子操作是线程安全的,原子操作只能保证命令全执行或者全不执行,并不会保证线程安全操作。例如数据库中的事务就是原子的,依旧还需要提供并发控制!!!!

    原子性操作是否线程安全?

    原文:https://stackoverflow.com/questions/14370575/why-are-atomic-operations-considered-thread-safe

    1.原子操作是针对访问共享变量的操作而言的。涉及局部变量访问的操作无所谓是否原子的。
    2.原子操作是从该操作的执行线程以外的线程来描述的,也就是说它只有在多线程环境下才有意义。


    原子操作得“不可分割”包括两层含义
    1.访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束要么尚未发生,
    即其他线程不会“看到”该操作执行了部分的中间效果。
    2.访问同一组共享变量的原子操作是不能够被交错的。

    此原子性与数据库原子性有区别:最主要区别是数据库的原子性,可以被其他线程看见中间状态,否则就不会有隔离级别的事了。

  • 相关阅读:
    【Hadoop】MapReduce练习:多job关联实现倒排索引
    【Hadoop】MapReduce练习:分科目等级并按分区统计学生以及人数
    【Zookeeper】利用zookeeper搭建Hdoop HA高可用
    【Linux】部署NTP时间同步服务器
    VSCode前端文件以服务器模式打开
    移动端公共方法封装
    常用浏览器及内核
    XHTML和HTML的区别
    javascript算法
    计算属性和侦听器
  • 原文地址:https://www.cnblogs.com/leodaxin/p/9544548.html
Copyright © 2011-2022 走看看