本文目录导读:

我来为您提供Java分布式锁的完整案例,包含多种实现方案:
基于Redis的分布式锁
1 基础版本 - 使用SETNX + 过期时间
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RedisLock {
private Jedis jedis;
private String lockKey;
private String lockValue;
private long expireTime = 30; // 默认过期时间(秒)
public RedisLock(Jedis jedis, String lockKey) {
this.jedis = jedis;
this.lockKey = lockKey;
}
/**
* 获取分布式锁
*/
public boolean lock(long waitTimeout, long expireTime) {
this.lockValue = UUID.randomUUID().toString();
this.expireTime = expireTime;
long startTime = System.currentTimeMillis();
try {
// 使用SET命令实现原子性加锁
while (true) {
SetParams params = new SetParams();
params.nx().px(expireTime * 1000);
String result = jedis.set(lockKey, lockValue, params);
if ("OK".equals(result)) {
System.out.println("获取锁成功: " + lockValue);
return true;
}
// 判断是否超时
if ((System.currentTimeMillis() - startTime) > waitTimeout) {
System.out.println("获取锁超时");
return false;
}
Thread.sleep(100); // 等待100ms后重试
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 释放分布式锁(使用Lua脚本保证原子性)
*/
public void unlock() {
String script = "if redis.call('get',KEYS[1]) == ARGV[1] then " +
"return redis.call('del',KEYS[1]) " +
"else return 0 end";
Long result = (Long) jedis.eval(script,
java.util.Collections.singletonList(lockKey),
java.util.Collections.singletonList(lockValue));
if (result > 0) {
System.out.println("释放锁成功: " + lockValue);
} else {
System.out.println("释放锁失败,锁已过期或被其他线程持有");
}
}
// 使用示例
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
RedisLock lock = new RedisLock(jedis, "product:1001");
try {
// 尝试获取锁,等待5秒,锁过期时间30秒
if (lock.lock(5000, 30)) {
// 执行业务逻辑
System.out.println("执行业务逻辑...");
Thread.sleep(2000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
2 使用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 RedissonLockDemo {
private RedissonClient redissonClient;
public void init() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("123456")
.setConnectionPoolSize(10)
.setConnectionMinimumIdleSize(5);
redissonClient = Redisson.create(config);
}
/**
* 使用Redisson分布式锁(自动续期机制)
*/
public void demoLock() {
RLock lock = redissonClient.getLock("order:lock");
try {
// 尝试加锁,等待2秒,持锁30秒
if (lock.tryLock(2, 30, TimeUnit.SECONDS)) {
System.out.println("获取锁成功");
// 执行业务逻辑
businessProcess();
} else {
System.out.println("获取锁失败");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("释放锁");
}
}
}
// 看门狗机制 - 自动续期
public void demoWithWatchDog() {
RLock lock = redissonClient.getLock("order:lock");
try {
// 不指定过期时间,使用看门狗自动续期(默认30秒,每10秒续期一次)
lock.lock();
System.out.println("获取锁成功,自动续期模式");
// 长时间业务操作,不需要担心锁过期
businessProcess();
} finally {
lock.unlock();
}
}
private void businessProcess() {
// 模拟业务逻辑
try {
Thread.sleep(5000);
System.out.println("业务处理完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
基于ZooKeeper的分布式锁
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ZookeeperLock implements Watcher {
private ZooKeeper zk;
private String root = "/locks";
private String lockName;
private String selfPath;
private String waitPath;
private CountDownLatch connectedLatch = new CountDownLatch(1);
private CountDownLatch waitLatch;
public ZookeeperLock(String connectString, String lockName) {
this.lockName = lockName;
try {
zk = new ZooKeeper(connectString, 3000, this);
connectedLatch.await();
// 创建根节点
if (zk.exists(root, false) == null) {
zk.create(root, new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 尝试获取锁(临时顺序节点实现)
*/
public boolean lock() {
try {
// 创建临时顺序节点
selfPath = zk.create(root + "/" + lockName,
new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("创建节点: " + selfPath);
// 获取所有子节点
List<String> children = zk.getChildren(root, false);
Collections.sort(children);
// 判断当前节点是否是最小节点
String selfNode = selfPath.substring(selfPath.lastIndexOf("/") + 1);
int index = children.indexOf(selfNode);
if (index == 0) {
// 最小节点,获取锁成功
System.out.println("获取锁成功");
return true;
} else {
// 监听前一个节点
waitPath = root + "/" + children.get(index - 1);
waitLatch = new CountDownLatch(1);
zk.exists(waitPath, true);
System.out.println("等待前一个节点释放: " + waitPath);
// 等待前一个节点删除
waitLatch.await();
return true;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 释放锁
*/
public void unlock() {
try {
if (zk != null && selfPath != null) {
zk.delete(selfPath, -1);
System.out.println("释放锁: " + selfPath);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (zk != null) {
zk.close();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
connectedLatch.countDown();
}
// 检查节点删除事件
if (event.getType() == Event.EventType.NodeDeleted) {
if (event.getPath().equals(waitPath)) {
waitLatch.countDown();
}
}
}
// 使用示例
public static void main(String[] args) {
ZookeeperLock lock = new ZookeeperLock("localhost:2181", "order");
try {
if (lock.lock()) {
System.out.println("执行业务逻辑...");
Thread.sleep(3000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
使用Spring Integration分布式锁
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@Service
public class SpringIntegrationLockDemo {
@Autowired
private RedisLockRegistry redisLockRegistry;
public void businessMethod(String orderId) {
// 创建锁
Lock lock = redisLockRegistry.obtain("lock:" + orderId);
boolean isLocked = false;
try {
// 尝试获取锁,等待5秒
isLocked = lock.tryLock(5, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("获取锁成功,执行订单: " + orderId);
// 业务逻辑
processOrder(orderId);
} else {
System.out.println("获取锁失败");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
if (isLocked) {
lock.unlock();
System.out.println("释放锁");
}
}
}
private void processOrder(String orderId) {
// 业务处理逻辑
System.out.println("处理订单业务...");
}
}
分布式锁实战应用示例
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁实战 - 电商订单防重
*/
public class OrderLockService {
private static final Logger logger = LoggerFactory.getLogger(OrderLockService.class);
private RedissonClient redissonClient;
public OrderLockService() {
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
redissonClient = Redisson.create(config);
}
/**
* 创建订单(使用分布式锁防止重复提交)
*/
public Result createOrder(OrderRequest request) {
// 使用用户ID+商品ID作为锁的key
String lockKey = "order:create:" + request.getUserId() + ":" + request.getProductId();
RLock lock = redissonClient.getLock(lockKey);
try {
// 尝试获取锁,等待3秒
if (!lock.tryLock(3, TimeUnit.SECONDS)) {
return Result.fail("操作太频繁,请稍后再试");
}
logger.info("获取锁成功, userId={}, productId={}",
request.getUserId(), request.getProductId());
// 检查是否已存在订单
if (checkOrderExist(request)) {
return Result.fail("订单已存在,请勿重复提交");
}
// 创建订单
Order order = createNewOrder(request);
// 扣减库存
reduceStock(request.getProductId(), request.getQuantity());
return Result.success(order);
} catch (Exception e) {
logger.error("创建订单失败", e);
return Result.fail("系统异常,请稍后再试");
} finally {
// 释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
logger.info("释放锁成功");
}
}
}
/**
* 模拟多线程并发下单测试
*/
public void testConcurrentOrder() {
int threadCount = 10;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
final int userId = i;
new Thread(() -> {
try {
latch.await();
OrderRequest request = new OrderRequest();
request.setUserId(userId);
request.setProductId(1001L);
request.setQuantity(1);
Result result = createOrder(request);
System.out.println("用户" + userId + "下单结果: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
latch.countDown();
}
}
private boolean checkOrderExist(OrderRequest request) {
// 查询数据库检查订单是否存在
return false;
}
private Order createNewOrder(OrderRequest request) {
// 创建订单逻辑
return new Order();
}
private void reduceStock(Long productId, Integer quantity) {
// 扣减库存逻辑
}
// 辅助类
static class OrderRequest {
private Integer userId;
private Long productId;
private Integer quantity;
// getters and setters...
public Integer getUserId() { return userId; }
public void setUserId(Integer userId) { this.userId = userId; }
public Long getProductId() { return productId; }
public void setProductId(Long productId) { this.productId = productId; }
public Integer getQuantity() { return quantity; }
public void setQuantity(Integer quantity) { this.quantity = quantity; }
}
static class Order {
private Long id;
private Integer userId;
// ...
}
static class Result {
private boolean success;
private String message;
private Object data;
public static Result success(Object data) {
Result result = new Result();
result.success = true;
result.data = data;
return result;
}
public static Result fail(String message) {
Result result = new Result();
result.success = false;
result.message = message;
return result;
}
@Override
public String toString() {
return "Result{success=" + success + ", message='" + message + "'}";
}
}
}
分布式锁配置类
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
@Configuration
public class DistributedLockConfig {
/**
* Redisson客户端配置
*/
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://192.168.1.100:6379")
.setPassword("123456")
.setDatabase(0)
.setConnectionPoolSize(50)
.setConnectionMinimumIdleSize(10)
.setTimeout(3000)
.setRetryAttempts(3)
.setRetryInterval(1500);
return Redisson.create(config);
}
/**
* Spring Integration 锁注册表
*/
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory connectionFactory) {
return new RedisLockRegistry(connectionFactory, "spring-integration-lock", 30000);
}
}
Maven依赖配置
<dependencies>
<!-- Redis Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
<!-- Redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.8</version>
</dependency>
<!-- ZooKeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.3</version>
</dependency>
<!-- Spring Integration Redis -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
<version>5.5.15</version>
</dependency>
<!-- Spring Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
关键设计要点
Redis分布式锁注意事项
- 原子性:使用SET NX EX命令确保原子操作
- 唯一标识:每个锁必须有唯一标识,防止误删其他线程的锁
- 过期时间:设置合理的过期时间,防止死锁
- 看门狗机制:Redisson的看门狗可以自动续期
ZooKeeper分布式锁
- 临时顺序节点:避免羊群效应
- 监听机制:只监听前一个节点
- 会话超时:处理心跳超时场景
最佳实践建议
// 锁的粒度设计
// - 细粒度:订单ID、用户ID
// - 粗粒度:库存、账户
// 超时时间设计
lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
// waitTime: 等待获取锁的时间
// leaseTime: 锁的持有时间
// 错误处理
catch (InterruptedException e) {
Thread.currentThread().interrupt();
// 恢复中断状态
}
这些案例涵盖了主流的分布式锁实现方案,您可以根据实际需求选择合适的方案,生产环境推荐使用Redisson,因为它提供了完善的自动续期机制和高可用支持。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播