搜索

首页  >  问答  >  正文

java - 基于redis开发的分布式锁,没达到预期效果.

思路是用redis的setNX来获取锁,并加上超时时间,在使用完后删除key来释放锁,没获取到锁的就一直轮询setNX来获取锁直到获取成功,但是每次删除完key之后并没有线程获取到了锁。不知道是什么原因。

代码放出来:

public class RedisLock {
    
    public static void lock(String key){
        lock(key,60);
    }
    
    public static void lock(String key,int time){
        Jedis jedis = RedisUtil.getClient();
        try {
            for (;;) {
                //这一步在unlock以后还一直返回的NULL并没有返回OK!!!
                String result = jedis.set(key, "1", "NX", "EX", time);
                System.out.println(result);
                if("OK".equals(result)){
                    break;
                }
                Thread.sleep(300);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            jedis.close();
        }
    }
    
    public static void unLock(String key){
        Jedis jedis = RedisUtil.getClient();
        try {
            jedis.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            jedis.close();
        }
    }
    
    public static void main(String[] args) throws Exception{
        System.out.println(RedisUtil.getClient().del("seckill"));
        //开启100条线程去抢购1000个商品
        for (int i = 0; i < 100; i++) {
            new SeckillThread(i).start();
        }
        
        while(Thread.activeCount()>1){
            Thread.sleep(1000);
        }
        System.out.println("还剩商品数量:"+SeckillServiceImpl.goodNum);
    }
}

class SeckillServiceImpl{
    
    //商品总数
    public static int goodNum = 1000;
    
    public void kill(){
        if(goodNum>0){
            goodNum--;
        }
    }
    
    public int getGoodNum(){
        return goodNum;
    }
}

class SeckillThread extends Thread{

    private int i;
    
    public SeckillThread(int i) {
        this.i = i;
    }


    @Override
    public void run() {
        try {
            SeckillServiceImpl seckillService = new SeckillServiceImpl();
            System.out.println("线程["+i+"]加锁");
            RedisLock.lock("seckill");
            seckillService.kill();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("线程["+i+"]释放锁");
            RedisLock.unLock("seckill");
        }
    }
    
}
迷茫迷茫2804 天前639

全部回复(3)我来回复

  • 巴扎黑

    巴扎黑2017-04-18 10:50:12

    用Redisson吧

    回复
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:50:12

    把你的kill方法写出来

    回复
    0
  • 迷茫

    迷茫2017-04-18 10:50:12

    先查查为什么一直是null吧

    回复
    0
  • 取消回复