import redis.clients.jedis.Jedis;
public class RedisLockDemo {
private static final String LOCK_KEY = "mylock";
private static final int LOCK_EXPIRE_TIME = 10; // 锁的过期时间,单位为秒
private static final int SLEEP_TIME = 100; // 获取锁失败后等待的时间,单位为毫秒
private Jedis jedis;
public RedisLockDemo() {
jedis = new Jedis("localhost"); // 连接本地Redis服务器
}
public boolean acquireLock() {
long startTime = System.currentTimeMillis();
while (true) {
String result = jedis.set(LOCK_KEY, "locked", "NX", "EX", LOCK_EXPIRE_TIME);
if ("OK".equals(result)) {
return true; // 获取锁成功
}
long elapsedTime = System.currentTimeMillis() - startTime;
if (elapsedTime > LOCK_EXPIRE_TIME * 1000) {
return false; // 获取锁超时,放弃获取锁
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public void releaseLock() {
jedis.del(LOCK_KEY); // 删除锁
}
public static void main(String[] args) {
RedisLockDemo lockDemo = new RedisLockDemo();
if (lockDemo.acquireLock()) {
try {
// 在获取锁成功后,执行需要加锁的业务逻辑
System.out.println("执行加锁后的业务逻辑");
Thread.sleep(5000); // 模拟业务逻辑执行时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lockDemo.releaseLock(); // 业务逻辑执行完毕后释放锁
}
} else {
System.out.println("获取锁失败");
}
}
}
```
代码解释:
1. `LOCK_KEY`:锁的名称,可以根据需要自定义。
2. `LOCK_EXPIRE_TIME`:锁的过期时间,需要根据业务逻辑的执行时间进行设置,过期时间应该大于业务逻辑的最长执行时间。
3. `SLEEP_TIME`:获取锁失败后等待的时间,可以根据需要进行调整,太短会增加Redis服务器的负载,太长会降低并发性能。
4. `acquireLock()`方法:尝试获取锁的方法,使用Redis的`SET`命令来设置一个带有过期时间的字符串,如果返回值为`OK`,说明获取锁成功,返回`true`;否则等待一段时间后再次尝试获取锁,直到超时时间到达或者获取锁成功为止。
5. `releaseLock()`方法:释放锁的方法,使用Redis的`DEL`命令将锁的键删除即可。
6. `main()`方法:使用`RedisLockDemo`类来实现分布式锁的示例,首先调用`acquireLock()`方法尝试获取锁,如果获取锁成功则执行需要加锁的业务逻辑,执行完毕后调用`releaseLock()`方法释放锁。
注意事项:
1. 在使用Redis实现分布式锁时,需要注意锁的过期时间和获取锁的等待时间,以避免锁过期或者获取锁失败的情况。
2. 需要注意锁的名称,不同的锁名称应该对应不同的业务逻辑,避免不同的业务逻辑之间互相干扰。
3. 如果业务逻辑执行时间较长,可以考虑将锁的过期时间设置为业务逻辑执行时间的两倍以上,以避免锁过期导致业务逻辑失败的情况。