- 本文要点
- 基于redis实现分布式锁demo
- 基于redis实现分布式锁原理
- 基于redis实现分布式锁优缺点
- 正文
- 基于redis实现分布式锁demo
package demo.redislock;
public class RedisLockDemo {
public static void main(String[] args) {
System.out.println("main started.");
try {
new Thread(new LockTask(), "THREAD_ONE").start();
new Thread(new LockTask(), "THREAD_TWO").start();
}catch (Exception e) {
e.printStackTrace();
}
}
}
class LockTask implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " started.");
RedisLock redisLock = new RedisLock("localhost");
try {
if (redisLock.lock("TEST", 100)) {
System.out.println(Thread.currentThread().getName() + " LOCKED");
try {
Thread.currentThread().sleep(10000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisLock.unlock("TEST");
} else {
System.out.println(Thread.currentThread().getName() + " LOCKED FAILED");
}
} finally {
redisLock.close();
}
}
}
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
public class RedisLock {
private Jedis jedis;
private static final String LOCK_VALUE = "1";
private static final String SUCCESS = "OK";
public RedisLock(String host) {
jedis = new Jedis(host);
jedis.connect();
}
public boolean lock(String key, int expireSeconds) {
try {
String result = jedis.set(key, LOCK_VALUE, SetParams.setParams().nx().ex(expireSeconds));
return SUCCESS.equalsIgnoreCase(result);
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
public boolean unlock(String key) {
try {
Long result = jedis.del(key);
return result == 1;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
void close() {
try {
jedis.close();
}catch (Exception e) {
e.printStackTrace();
}
return;
}
}
执行结果:
THREAD_ONE 和 THREAD_TWO 其中一个线程拿到了分布式锁
执行结果.png
- 基于redis实现分布式锁原理
基于redis的set命令实现分布式锁
# 当LOCKKEY的值不存在时, 设置LOCKKEY, 并且在100秒后过期
set LOCKKEY LOCKVALUE nx ex 100
- 基于redis实现分布式锁优缺点
缺点:
a. 不支持可重入
b. 线程1加锁后, 如果线程1在超时时间内,没有执行完自身逻辑, 则其他线程也能获取到分布式锁
c. 线程1在master节点上加锁成功后, 还未同步到其他节点上, 此时master节点宕机了, 那么其他线程仍能够获取到这个锁
优点:
a.私用redis锁可以让未获取到锁到线程不执行业务处理, 可以有效减少业务数据库压力