用redis实现秒杀

来源:互联网 发布:淘宝哪里有卖高仿手表 编辑:程序博客网 时间:2024/04/28 17:07

今日在研究秒杀系统,用数据库的乐观锁可以实现,但是在高并发下可能并不好,所以就想到了缓存系统redis,因为redis本身也有锁机制,废话不多说,直接上代码,请大神指点不足的地方。

class A{

private ExecutorService executorService = Executors.newFixedThreadPool(8);

private RedisTemplate<String, String> redisTemplate;

 public void initTestWatch(){
        BoundHashOperations<String, String, Integer> redisHash = redisTemplate.boundHashOps("test_redis_watch");//在redis里存放一百个苹果
        redisHash.put("test_redis_watch", 100);//一百个苹果

    //模仿一百零一个用户抢苹果
        for(int i = 1; i <= 101; i ++){
            executorService.execute(new MyRunnable(redisTemplate,"用户"+i));
          }

        
    }

}



public class MyRunnable implements Runnable{
    private Logger logger = LoggerTools.getInstance(getClass());
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    private String name;
    
     public MyRunnable(RedisTemplate<String, String> redisTemplate,String name) {
         this.redisTemplate = redisTemplate;
         this.name = name;
     }
    
    @Override
    public void run() {
        
      while(true){
          try{
              logger.info("{}进来,秒杀苹果。。。。",name);
              boolean b =  RedisInfoOperate.setSuccess(redisTemplate, "test_redis_watch_111", "");
               if(b){
                   BoundHashOperations<String, String, Integer> redisHash = redisTemplate.boundHashOps("test_redis_watch");        
                    Integer count = redisHash.get("test_redis_watch");//数量
                    if(count > 0){
                        count--;
                        logger.info("{}取走一个苹果,剩余{}苹果",name,count);
                        redisHash.put("test_redis_watch", count);
                    }else{
                         logger.info("{}没抢到,因为卖光了",name);
                        
                    }
                    RedisInfoOperate.delKeyLock(redisTemplate, "test_redis_watch_111");
                    break;
               }
              logger.info("用户{}排队等待中。。。。",name);
              Thread.sleep(500);
          }catch(Exception e){
              e.printStackTrace();
          }
        
      }
       
    }

}




public class RedisInfoOperate {
    
    /**
     * 使用redis进行并发控制
     * @param redisTemplate
     * @param key
     * @param value
     * @return    
     * @return:       boolean    
     * @throws
     * @author        yuanxin
     * @Date          2017年5月24日 下午3:22:43
     */
    @SuppressWarnings("unchecked")
    public static boolean setSuccess(RedisTemplate redisTemplate,final String key,final String value){
        boolean flag = false ;
        flag = (boolean) redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                boolean flag = connection.setNX(key.getBytes(), value.getBytes());
                return flag ;
            }
            
        });
        
        return flag;
    }
    
    /***
     * 判断key值是否存在
     * @param redisTemplate
     * @param key
     * @return    
     * @return:       boolean    
     * @throws
     * @author        yuanxin
     * @Date          2017年5月25日 上午11:29:28
     */
    @SuppressWarnings("unchecked")
    public static boolean isExit(RedisTemplate redisTemplate,final String key){
        boolean flag = false ;
        flag = (boolean) redisTemplate.execute(new RedisCallback() {

            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.exists(key.getBytes());
            }
            
        });
        
        return flag;
    }
    
    /**
     * 删除并发锁数据(防止数据太多)
     * @param redisTemplate
     * @param key    
     * @return:       void    
     * @throws
     * @author        yuanxin
     * @Date          2017年5月24日 下午3:24:56
     */
    @SuppressWarnings("unchecked")
    public static void delKeyLock(RedisTemplate redisTemplate,final String key){
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                connection.del(key.getBytes());
                return null ;
            }
        });
    }
    
    /***
     * 模糊匹配删除
     * @param redisTemplate
     * @param key    
     * @return:       void    
     * @throws
     * @author        yuanxin
     * @Date          2017年5月25日 上午11:29:58
     */
    @SuppressWarnings("unchecked")
    public static void delKeyLockMutil(RedisTemplate redisTemplate,final String key){
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                Set<byte[]> keys = connection.keys((key+"*").getBytes());
                if(!keys.isEmpty()){
                    for(byte[] bytes : keys){
                        System.out.println(bytes[bytes.length -1]);
                        connection.del(bytes);
                    }
                }
                
                return null ;
            }
        });
    }
}

原创粉丝点击