AtomicInteger和reidis配合实现分布式锁代码
时间: 2023-10-19 10:05:01 浏览: 87
基于Redis分布式锁的实现代码
使用AtomicInteger和redis配合实现分布式锁的代码如下所示:
```java
public class DistributedLock {
private final static String LOCK_PREFIX = "distributed_lock:";
private final static int LOCK_EXPIRE = 60 * 1000; // 锁过期时间
private Jedis jedis;
private String lockKey;
private AtomicInteger counter = new AtomicInteger(0);
private int lockCount = 0;
public DistributedLock(Jedis jedis, String lockKey) {
this.jedis = jedis;
this.lockKey = LOCK_PREFIX + lockKey;
}
/**
* 获取分布式锁
* @return true:获取锁成功;false:获取锁失败
*/
public boolean lock() {
String value = String.valueOf(Thread.currentThread().getId());
long expireTime = System.currentTimeMillis() + LOCK_EXPIRE + 1;
// 尝试获取锁
if (jedis.setnx(lockKey, value) == 1) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
// 判断是否重入
if (value.equals(jedis.get(lockKey))) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
// 获取锁失败,等待其他线程释放锁
while (System.currentTimeMillis() < expireTime) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (jedis.setnx(lockKey, value) == 1) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
if (value.equals(jedis.get(lockKey))) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
}
return false;
}
/**
* 释放分布式锁
*/
public void unlock() {
if (lockCount == 1) {
jedis.del(lockKey);
} else {
int count = counter.decrementAndGet();
if (count == 0) {
jedis.del(lockKey);
}
}
}
/**
* 重入分布式锁
*/
public boolean reentrantLock() {
String value = String.valueOf(Thread.currentThread().getId());
long expireTime = System.currentTimeMillis() + LOCK_EXPIRE + 1;
// 判断是否已经获取锁
if (value.equals(jedis.get(lockKey))) {
lockCount++;
return true;
}
// 获取锁失败,等待其他线程释放锁
while (System.currentTimeMillis() < expireTime) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (jedis.setnx(lockKey, value) == 1) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
if (value.equals(jedis.get(lockKey))) {
jedis.expire(lockKey, LOCK_EXPIRE);
lockCount = 1;
return true;
}
}
return false;
}
}
```
说明:
1. 使用AtomicInteger记录当前线程持有锁的数量,以便实现重入锁。
2. lock()方法尝试获取锁,如果获取成功,则返回true;如果锁已经被其他线程获取,则等待一段时间后再次尝试获取锁。
3. unlock()方法释放锁,如果当前线程持有的锁数量为1,则直接释放锁;否则减少持有锁的数量。
4. reentrantLock()方法用于实现重入锁,如果当前线程已经持有锁,则只需要增加持有锁的数量即可。
阅读全文