redis并发测试

3 篇文章 0 订阅
1 篇文章 0 订阅

1、使用redis实现简单的计数

@Setter
@Getter
public class RedisUtil implements InitializingBean {

    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void afterPropertiesSet(){ }
    
    public void set(String key, String val) {
        stringRedisTemplate.opsForValue().set(key, val);
    }
    
    public void setExpire(String key, String val, long timeout, TimeUnit unit) {
        stringRedisTemplate.opsForValue().set(key, val);
        stringRedisTemplate.expire(key, timeout, unit);
    }
    
    public void set(String key, Object val) {
        String value = JSON.toJSONString(val);
        stringRedisTemplate.opsForValue().set(key, value);
    }
    
    public void setExpire(String key, Object val, long timeout, TimeUnit unit) {
        String value = JSON.toJSONString(val);
        stringRedisTemplate.opsForValue().set(key, value);
        stringRedisTemplate.expire(key, timeout, unit);
    }
    
    public String get(String key) {
        String val = stringRedisTemplate.opsForValue().get(key);
        return val;
    } 
    
    public boolean hasKey(String key) {
        return stringRedisTemplate.hasKey(key);
    }
    
    public void delete(String key) {
        stringRedisTemplate.delete(key);
    }

    public long increment(String key) {
        long val;
        try{
            val = stringRedisTemplate.opsForValue().increment(key, 1L);
            if(val >= Long.MAX_VALUE) {
                stringRedisTemplate.opsForValue().set(key, "1");
                val = 0L;
            }    
        } catch(Exception e) {
            stringRedisTemplate.opsForValue().set(key, "1");
            val = 0L;
        }
        return val;
    }
    
    public long incrementExpire(String key, long timeout, TimeUnit unit) {
        long val;
        try{
            val = stringRedisTemplate.opsForValue().increment(key, 1L);
            if(val >= Long.MAX_VALUE) {
                stringRedisTemplate.opsForValue().set(key,"1");
                val = 1L;
            }
        } catch(Exception e) {
            stringRedisTemplate.opsForValue().set(key, "1");
            val = 1L;
        }
        if(val==1L) {
            stringRedisTemplate.expire(key, timeout, unit);
        }
        return val;
    }

    public void convertAndSend(String channelTopic, String message){
        stringRedisTemplate.convertAndSend(channelTopic,message);
    }


    /**
     * redis 获取自增值
     *
     * @param key key
     * @param incrBy 增量值
     * @param timeout 超时时间(seconds)
     * @return 返回结果
     */
    public long increment(final String key, final long incrBy, final long timeout,final TimeUnit timeUnit) {
        long count = stringRedisTemplate.opsForValue().increment(key, incrBy);
        if(count == incrBy && timeout > 0) {
            stringRedisTemplate.expire(key, timeout, timeUnit);
        }
        return count;
    }

    /**
     * redis 获取自增值
     *
     * @param key key
     * @param incrBy 增量值
     * @return 返回结果
     */
    public long decrement(final String key, final long incrBy) {
        return  stringRedisTemplate.opsForValue().increment(key, incrBy);
    }
}

2、使用CountDownLatch对redis计数功能进行并发测试

CountDownLatch其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。

并发测试使用CountDownLatch的两个使用场景

(1)最大程度上实现并行

(2)让当前线程等待所有线程执行结束开始执行

CountDownLatch还有一个应用场景:死锁检测

CountDownLatch使用缺点:不能够重复使用,只能在初始化的时候进行赋值。

public class SimulationTest extends BaseCacheTest {

    @Autowired
    private RedisUtil redisUtil;

    @Test
    public void simulationParallel(){
        SimulationTest simulationTest = new SimulationTest();
        simulationTest.startTaskAllInOnce(100,new Task());
        System.out.println(redisUtil.get("smart"));
    }

    public long startTaskAllInOnce(int threadNums,final Runnable task){
        //闭锁
        final CountDownLatch begin = new CountDownLatch(1);
        final CountDownLatch end  = new CountDownLatch(threadNums);

        for(int i = 0; i < threadNums; i++){
            Thread thread = new Thread(){
                @Override
                public void run() {
                    try {
                        begin.await();
                        try{
                            task.run();
                        }catch (Exception e){
                            e.printStackTrace();
                        }finally {
                            end.countDown();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        }
        long startTime = System.nanoTime();
        System.out.println("All thread is ready.............");
        begin.countDown();
        try {
            end.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("All thread is completed..........");
        return System.nanoTime()-startTime;
    }


    class Task implements Runnable{
        @Override
        public void run() {
            redisUtil.increment("smart",1,1, TimeUnit.MINUTES);
        }
    }
}

如果不对的地方,请各位大佬指正

参考博客:

(1)https://zapldy.iteye.com/blog/746458

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值