java分布式锁代码
时间: 2023-01-29 12:12:10 浏览: 127
在 Java 中,可以使用 java.util.concurrent 包中的 ReentrantLock 类来实现分布式锁。
下面是一个示例代码:
```
import java.util.concurrent.locks.ReentrantLock;
public class DistributedLock {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// 获取锁
lock.lock();
try {
// 这里是临界区代码,在这里进行读写操作
} finally {
// 释放锁
lock.unlock();
}
}
}
```
在上面的代码中,首先使用 lock() 方法获取锁,然后在 try-finally 块中执行临界区代码。最后使用 unlock() 方法释放锁。
注意:在使用 ReentrantLock 类时,一定要记得在 finally 块中释放锁,否则可能会造成死锁。
相关问题
java 分布式锁代码
以下是一个基于 Redis 的 Java 分布式锁的示例代码:
```java
import redis.clients.jedis.Jedis;
public class RedisDistributedLock {
private Jedis jedis;
private String lockKey;
private int expireTime;
private boolean locked = false;
public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) {
this.jedis = jedis;
this.lockKey = lockKey;
this.expireTime = expireTime;
}
public boolean lock() {
long nowTime = System.currentTimeMillis();
long expireTime = nowTime + this.expireTime + 1;
String expireStr = String.valueOf(expireTime);
if (this.jedis.setnx(this.lockKey, expireStr) == 1) {
this.locked = true;
return true;
}
String currentValueStr = this.jedis.get(this.lockKey);
if (currentValueStr != null && Long.parseLong(currentValueStr) < nowTime) {
String oldValueStr = this.jedis.getSet(this.lockKey, expireStr);
if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
this.locked = true;
return true;
}
}
return false;
}
public void unlock() {
if (this.locked) {
this.jedis.del(this.lockKey);
this.locked = false;
}
}
}
```
使用示例:
```java
Jedis jedis = new Jedis("localhost");
RedisDistributedLock lock = new RedisDistributedLock(jedis, "my_lock", 3000);
if (lock.lock()) {
try {
// 获得锁后的业务处理
} finally {
lock.unlock();
}
}
```
这个示例代码基于 Redis 实现了一个简单的分布式锁。使用 `setnx` 命令尝试设置锁,如果返回值为 1,则表示获取到了锁;否则通过 `get` 命令获取当前锁的过期时间,判断锁是否已经过期,如果过期则使用 `getset` 命令设置新的过期时间并返回旧的过期时间,如果旧的过期时间等于之前获取的过期时间,则表示获取到了锁。在获取到锁之后,可以进行业务处理,处理完成后需要调用 `unlock` 方法释放锁。
java 分布式锁代码实现
Java 中分布式锁的实现通常涉及到以下几个步骤,以基于 Redis 为例,因为 Redis 是一个常用的分布式缓存和键值存储,常被用作分布式锁的后端:
1. **客户端获取锁**:
- 客户端首先尝试从 Redis 获取一个特定的 key(例如 "distributed_lock" 加上唯一ID),如果这个 key不存在或过期,则认为锁未被占用。
```java
String lockKey = "distributed_lock:" + uniqueId;
String value = redisClient.get(lockKey);
if (value == null) {
// 尝试获取锁
boolean acquired = redisClient.setnx(lockKey, UUID.randomUUID().toString());
if (acquired) {
// 锁已被获取,后续操作
try {
// 执行业务逻辑
} finally {
// 释放锁
redisClient.del(lockKey);
}
} else {
// 锁已被其他节点获取,等待或者重试
}
}
```
2. **超时处理**:
- 在获取锁之前设置一个超时时间,比如使用 `JedisScript` 和 `ScriptingSupport` 来设置。
```java
JedisScript script = new JedisScript("if redis.call('get', KEYS) == ARGV then return 1 else return 0 end");
long result = redisClient.eval(script, Collections.singletonList(lockKey), Collections.singletonList(uniqueId));
if (result == 1) {
// 获取锁成功
} else {
// 超时或锁已被其他节点获取
}
```
3. **分布式锁的优化**:
- 可能会使用乐观锁(如 `setnx` 或 `INCR`)或者基于版本号的乐观锁,结合时间戳以减少死锁。
- 使用红黑树等数据结构提高锁的获取效率。
4. **解锁**:
- 在任务执行完毕后,需要确保正确地删除或更新锁定的 key,以便其他节点可以获取。
阅读全文