1、redis不能保证你的代码线程安全

总结:redis的每个操作是原子操作,但是在java代码中组合起来的redis操作不是原子操作,因此需要借用redis来实现分布式锁,解决并发问题。

虽然redis的操作是原子操作,但如果在java中分步操作的话,依旧会出现并发问题。
例如:先获取redis中的number,加1后再放回redis,如果10个线程同时处理的话,会出现并发问题。

public class test {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    Redis ru = new Redis();
                    //获取redis的值
                    Integer number= ru.getInteger("number");
                    number++;
                    //加一再放回redis
                    ru.set("number",number.toString());
                    System.out.println(Thread.currentThread().getName() +"---->result:" +  number) ;
                }
            });
            thread1.start();
        }
    }

}

结果为

image.png

在redis中的数据如图
image.png

由于初始number为0,运行10次后,应该为10,但是数据库中的number值为1,出现了错误。因为虽然redis的set和get操作是原子操作,但是在java代码中这两步分开了 ,所以还是没法兼容多线程的操作。后面我们会慢慢介绍如何通过redis的原子操作解决多线程并发的问题。

附java中操作jedis的代码:

package com.dazhiyouqiu.api;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class Redis {

        private Jedis jedis;
        private JedisPool jedisPool;

        public Redis() {
            initialPool();
            jedis = jedisPool.getResource();
        }


        private void initialPool() {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxWaitMillis(100000l);
            config.setMaxIdle(20);
            config.setTestOnBorrow(false);

            jedisPool = new JedisPool(config, "127.0.0.1", 6379,100000);

        }


        public String get(String key) {
            String getStr = jedis.get(key);
            return getStr;
        }

        public Integer getInteger(String key){
            String re =jedis.get(key);
            return re==null?0:Integer.valueOf(re);
        }

        public String set(String key, String value) {
            String setStr = jedis.set(key, value);
            return setStr;
        }

        public Long delete(String key){
            Long re =jedis.del(key);
            return re;
        }

    // NX是不存在时才set, XX是存在时才set, EX是秒,PX是毫秒
    public String set(String key, String value,long expireSecond) {

        String setStr = jedis.set(key, value,"NX","EX",expireSecond);
        return setStr;
    }

}

你可能感兴趣的:(1、redis不能保证你的代码线程安全)