1. 程式人生 > >分散式鎖的幾種實現方法:redis實現分散式鎖

分散式鎖的幾種實現方法:redis實現分散式鎖


使用失效的方式實現分散式鎖(推薦)


import redis.clients.jedis.Jedis;

/**
 * 使用redis實現分散式鎖(推薦)
 *
 */
public class JedLock {

    private static final String LOCK_KEY = "jedis_lock";
    private static final int RETRY_TIME = 10 * 1000; //等待鎖的時間
    private static final int EXPIRE_TIME = 60 * 1000;//鎖超時的時間
    private boolean locked;
    private long lockValue;

    public synchronized boolean lock(Jedis jedis){
        int retryTime = RETRY_TIME;
        try {
            while (retryTime > 0) {
                lockValue = System.nanoTime();
                if ("OK".equalsIgnoreCase(jedis.set(LOCK_KEY, String.valueOf(lockValue), "NX", "PX", EXPIRE_TIME))) {
                    locked = true;
                    return locked;
                }
                retryTime -= 100;
                Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public synchronized void unlock(Jedis jedis){
        if(locked) {
            String currLockVal = jedis.get(LOCK_KEY);
            if(currLockVal!=null && Long.valueOf(currLockVal) == lockValue){
                jedis.del(LOCK_KEY);
                locked = false;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Jedis jedis = new Jedis("192.168.75.129", 6379);
        JedLock redLock = new JedLock();
        if(redLock.lock(jedis)) {
            System.out.println(Thread.currentThread().getName() + ": 獲得鎖!");
            Thread.sleep(25000);
            System.out.println(Thread.currentThread().getName() + ": 處理完成!");
            redLock.unlock(jedis);
            System.out.println(Thread.currentThread().getName() + ": 釋放鎖!");
        }else {
            System.out.println("get lock fail!!!");
        }
    }
}


判斷鎖超時的方式實現分散式鎖


import redis.clients.jedis.Jedis;

/**
 * 使用redis實現分散式鎖
 *
 */
public class RedLock {
    private static final String LOCK_KEY = "redis_lock";
    private static final int RETRY_TIME = 10 * 1000; //等待鎖的時間
    private static final int EXPIRE_TIME = 60 * 1000;//鎖超時的時間
    private boolean locked;
    private long lockValue;

    public synchronized boolean lock(Jedis jedis){
        int retryTime = RETRY_TIME;
        try {
            while (retryTime > 0) {
                lockValue = System.currentTimeMillis() + EXPIRE_TIME + 1;//鎖到期時間
                String lockValueStr = String.valueOf(lockValue);
                //判斷能否獲取鎖
                if (jedis.setnx(LOCK_KEY, lockValueStr) == 1) {
                    //成功獲取鎖
                    locked = true;
                    return locked;
                }
                String currLockVal = jedis.get(LOCK_KEY);
                // 判斷鎖是否已經失效
                if (currLockVal != null && Long.valueOf(currLockVal) < System.currentTimeMillis()) {
                    //鎖已經失效,使用命令getset設定最新的過期時間
                    String oldLockVal = jedis.getSet(LOCK_KEY, lockValueStr);
                    //判斷鎖是否已經被搶佔
                    if (oldLockVal != null && oldLockVal.equals(currLockVal)) {
                        locked = true;
                        return locked;
                    }
                }
                retryTime -= 100;
                Thread.sleep(100);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    public synchronized void unlock(Jedis jedis){
        if(locked) {
            String currLockVal = jedis.get(LOCK_KEY);
            if(currLockVal != null && Long.valueOf(currLockVal) == lockValue) {
                jedis.del(LOCK_KEY);
                locked = false;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Jedis jedis = new Jedis("192.168.75.129", 6379);
        RedLock redLock = new RedLock();
        if(redLock.lock(jedis)) {
            System.out.println(Thread.currentThread().getName() + ": 獲得鎖!");
            Thread.sleep(150000);
            System.out.println(Thread.currentThread().getName() + ": 處理完成!");
            redLock.unlock(jedis);
            System.out.println(Thread.currentThread().getName() + ": 釋放鎖!");
        }else {
            System.out.println("get lock fail!!!");
        }
    }
}