本文目录导读:

我来为您提供几种Java实现分布式锁的完整案例,包括基于Redis和ZooKeeper的实现。
基于Redis的分布式锁
使用Jedis实现(最基础版)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
import java.util.UUID;
public class RedisDistributedLock {
private static final String LOCK_KEY = "distributed_lock";
private static final long LOCK_EXPIRE_TIME = 30000; // 锁过期时间:30秒
private Jedis jedis;
private String lockValue;
public RedisDistributedLock(Jedis jedis) {
this.jedis = jedis;
}
/**
* 获取分布式锁
*/
public boolean tryLock() {
// 生成唯一标识,用于释放锁时校验
lockValue = UUID.randomUUID().toString();
// 使用SET命令的NX和EX参数实现原子性操作
SetParams params = SetParams.setParams()
.nx() // 不存在时才设置
.ex(30); // 设置过期时间30秒
String result = jedis.set(LOCK_KEY, lockValue, params);
return "OK".equals(result);
}
/**
* 释放分布式锁
*/
public void unlock() {
// 使用Lua脚本保证原子性
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) " +
"else return 0 end";
jedis.eval(script,
java.util.Collections.singletonList(LOCK_KEY),
java.util.Collections.singletonList(lockValue));
}
}
使用Spring Data Redis实现(生产环境推荐)
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
@Component
public class RedisLockUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;
private static final String LOCK_PREFIX = "redis:lock:";
private static final String UNLOCK_SCRIPT =
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
" return redis.call('del', KEYS[1]) " +
"else " +
" return 0 " +
"end";
/**
* 加锁
* @param lockKey 锁的key
* @param requestId 请求标识(用于防止误删)
* @param expireTime 过期时间
* @return 是否成功
*/
public boolean lock(String lockKey, String requestId, long expireTime) {
try {
String key = LOCK_PREFIX + lockKey;
return Boolean.TRUE.equals(
redisTemplate.opsForValue().setIfAbsent(key, requestId, expireTime, TimeUnit.SECONDS)
);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 解锁
*/
public boolean unlock(String lockKey, String requestId) {
try {
String key = LOCK_PREFIX + lockKey;
// 使用Lua脚本保证原子性
DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
Long result = redisTemplate.execute(script,
Collections.singletonList(key),
requestId);
return result != null && result > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Redisson分布式锁(功能最全)
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;
public class RedissonDistributedLock {
private RedissonClient redissonClient;
/**
* 初始化Redisson
*/
public void init() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("password") // 有密码时配置
.setDatabase(0);
redissonClient = Redisson.create(config);
}
/**
* 使用Redisson实现分布式锁
*/
public void operateWithLock() {
RLock lock = redissonClient.getLock("business-lock");
try {
// 尝试加锁,最多等待10秒,锁自动释放时间为30秒
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
try {
// 业务处理
System.out.println("获取锁成功,执行业务逻辑...");
Thread.sleep(5000);
} finally {
// 释放锁(只有持有者才能释放)
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} else {
System.out.println("获取锁失败");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
/**
* 使用看门狗机制自动续期
*/
public void operateWithWatchdog() {
RLock lock = redissonClient.getLock("watchdog-lock");
try {
// 默认锁30秒,看门狗每隔10秒自动续期
lock.lock();
try {
// 业务处理(可以长时间运行)
System.out.println("执行业务逻辑,看门狗会自动续期...");
Thread.sleep(60000);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
基于ZooKeeper的分布式锁
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class ZookeeperDistributedLock {
private CuratorFramework client;
public ZookeeperDistributedLock() {
// 初始化ZooKeeper客户端
client = CuratorFrameworkFactory.builder()
.connectString("localhost:2181")
.sessionTimeoutMs(5000)
.connectionTimeoutMs(3000)
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
client.start();
}
/**
* 使用Curator实现分布式锁
*/
public void operateWithLock() {
// 创建分布式锁
InterProcessMutex lock = new InterProcessMutex(client, "/locks/business-lock");
try {
// 获取锁(最多等待10秒)
boolean isLocked = lock.acquire(10, TimeUnit.SECONDS);
if (isLocked) {
try {
// 业务处理
System.out.println("获取ZooKeeper锁成功,执行业务逻辑...");
Thread.sleep(5000);
} finally {
// 释放锁
lock.release();
System.out.println("释放锁成功");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
完整的业务使用案例
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class InventoryService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private RedisLockUtil redisLockUtil;
private static final String INVENTORY_KEY = "inventory:product:1001";
/**
* 扣减库存(使用分布式锁)
*/
public boolean deductStock(String orderId) {
// 生成请求ID
String requestId = orderId + ":" + System.currentTimeMillis();
String lockKey = "product:1001:stock";
// 尝试获取锁
boolean isLocked = redisLockUtil.lock(lockKey, requestId, 30);
if (!isLocked) {
System.out.println("获取分布式锁失败,订单:" + orderId);
return false;
}
try {
// 检查库存
Object stockObj = redisTemplate.opsForValue().get(INVENTORY_KEY);
int stock = stockObj == null ? 0 : Integer.parseInt(stockObj.toString());
if (stock <= 0) {
System.out.println("库存不足,订单:" + orderId);
return false;
}
// 扣减库存
redisTemplate.opsForValue().set(INVENTORY_KEY, String.valueOf(stock - 1));
System.out.println("扣减库存成功,剩余库存:" + (stock - 1) + ",订单:" + orderId);
// 记录订单
saveOrder(orderId, stock - 1);
return true;
} finally {
// 释放锁
redisLockUtil.unlock(lockKey, requestId);
}
}
private void saveOrder(String orderId, int remainingStock) {
// 保存订单到数据库
System.out.println("保存订单:" + orderId + ",剩余库存:" + remainingStock);
}
}
使用Redisson的完整示例
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class RedissonLockDemo {
private RedissonClient redissonClient;
public RedissonLockDemo() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setConnectionPoolSize(10)
.setConnectionMinimumIdleSize(5);
redissonClient = Redisson.create(config);
}
/**
* 分布式锁工具方法
*/
public <T> T executeWithLock(String lockName,
long waitTime,
long leaseTime,
LockCallback<T> callback) {
RLock lock = redissonClient.getLock(lockName);
try {
// 尝试获取锁
boolean isLocked = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
if (!isLocked) {
throw new RuntimeException("获取锁超时,锁名称:" + lockName);
}
try {
// 执行业务逻辑
return callback.execute();
} finally {
// 释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("线程被中断", e);
} finally {
// 可选:关闭连接
}
}
@FunctionalInterface
public interface LockCallback<T> {
T execute();
}
// 使用示例
public static void main(String[] args) {
RedissonLockDemo demo = new RedissonLockDemo();
// 执行带锁的业务逻辑
String result = demo.executeWithLock("product-lock", 10, 30, () -> {
System.out.println("执行业务逻辑...");
return "业务执行成功";
});
System.out.println("结果:" + result);
}
}
分布式锁要点总结
核心要点
- 原子性:加锁和解锁操作必须是原子性的
- 唯一定标识:每个锁需要唯一标识,防止误删
- 过期时间:防止死锁
- 锁续期:处理长任务(Redisson看门狗)
选择建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Redis SETNX | 简单、性能高 | 可能出现主从切换问题 | 中小型系统 |
| Redisson | 功能完善、自动续期 | 依赖Redisson客户端 | 生产环境推荐 |
| ZooKeeper | 强一致、节点监控 | 性能相对较低 | 对一致性要求高的场景 |
注意事项
- 锁的粒度要合适,避免过大或过小
- 业务执行时间要小于锁的过期时间
- 考虑高可用部署(Redis集群、ZooKeeper集群)
- 做好异常处理和降级方案
有任何具体需求或疑问,欢迎继续探讨!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播