java - 基于redis开发的分布式锁,没达到预期效果.
迷茫
迷茫 2017-04-18 10:48:12
0
3
624

思路是用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");
        }
    }
    
}
迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回覆(3)
巴扎黑

用Redisson吧

Peter_Zhu

把你的kill方法寫出來

迷茫

先查為什麼一直是null吧

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板