您的位置:首页 > 游戏 > 手游 > discuz应用中心破解_2023年的毒株又来了_网络推广员的前景_长沙网站制作主要公司

discuz应用中心破解_2023年的毒株又来了_网络推广员的前景_长沙网站制作主要公司

2025/3/7 6:48:45 来源:https://blog.csdn.net/m0_50742275/article/details/145967054  浏览:    关键词:discuz应用中心破解_2023年的毒株又来了_网络推广员的前景_长沙网站制作主要公司
discuz应用中心破解_2023年的毒株又来了_网络推广员的前景_长沙网站制作主要公司

一、Redisson 分布式锁的工作原理

1. 基本机制

Redisson 实现分布式锁的核心是基于 Redis 的 SET 命令。具体来说,Redisson 使用以下命令来获取锁:

SET resource_name my_random_value NX PX 30000
  • resource_name:锁的名称。
  • my_random_value:每个客户端生成的唯一标识符(通常是 UUID + 线程 ID),用于确保锁只能由持有者释放。
  • NX:只有当键不存在时才设置键值。
  • PX 30000:设置键的过期时间为 30 秒(毫秒为单位)。

这种机制确保了即使客户端崩溃或网络故障,锁也会在一定时间后自动释放,避免死锁问题。

2. 看门狗机制

为了防止长时间运行的任务因锁超时而被意外释放,Redisson 提供了“看门狗”机制。当一个线程成功获取锁后,Redisson 会启动一个后台线程,定期检查并延长锁的有效期。默认情况下,锁的有效期为 30 秒,但看门狗会在到期前自动续期,直到任务完成并显式释放锁。

可以通过以下方式禁用看门狗机制:

lock.lock(10, TimeUnit.SECONDS); // 锁持有时间为10秒,不启用看门狗

二、高级功能

1. 可重入锁(Reentrant Lock)

Redisson 支持可重入锁,允许同一个线程多次获取同一把锁而不发生死锁。这对于需要递归调用的方法非常有用。

RLock lock = redisson.getLock("myLock");// 获取锁
lock.lock();
try {// 执行业务逻辑
} finally {// 释放锁lock.unlock();
}

异步获取锁:

lock.lockAsync().thenAccept(result -> {if (result) {try {// 执行业务逻辑} finally {lock.unlockAsync();}}
});
2. 公平锁(Fair Lock)

公平锁按照请求顺序分配锁,避免饥饿现象。即先请求锁的线程优先获得锁。

RFairLock fairLock = redisson.getFairLock("myFairLock");fairLock.lock(); // 获取锁
try {// 执行业务逻辑
} finally {fairLock.unlock(); // 释放锁
}
3. 联锁(MultiLock)

联锁允许多个锁同时生效,只有当所有锁都获取成功时才算获取成功。

RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);multiLock.lock(); // 获取联锁
try {// 执行业务逻辑
} finally {multiLock.unlock(); // 释放联锁
}
4. 红锁(RedLock)

红锁在多个独立的 Redis 节点上实现分布式锁,提高系统的可靠性和容错能力。通常需要至少三个节点来保证高可用性。

Config config = new Config();
config.useClusterServers().addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:6380", "redis://127.0.0.1:6381");RedissonClient redisson = Redisson.create(config);RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);redLock.lock(); // 获取红锁
try {// 执行业务逻辑
} finally {redLock.unlock(); // 释放红锁
}
5. 读写锁(ReadWriteLock)

读写锁允许多个读操作同时进行,但写操作互斥。适合多读少写的场景。

RReadWriteLock rwLock = redisson.getReadWriteLock("myRWLock");// 获取读锁
rwLock.readLock().lock();
try {// 执行读操作
} finally {rwLock.readLock().unlock();
}// 获取写锁
rwLock.writeLock().lock();
try {// 执行写操作
} finally {rwLock.writeLock().unlock();
}

三、应用场景

1. 资源竞争

在多个实例或进程中访问共享资源(如文件系统、数据库记录等)时,确保同一时刻只有一个实例进行操作。

2. 定时任务调度

防止多个实例同时执行相同的定时任务,确保任务在同一时间内只执行一次。

3. 缓存一致性

当多个实例尝试更新同一缓存项时,使用分布式锁可以避免数据不一致的问题。

4. 高并发交易处理

在金融系统中,确保同一账户的交易在同一时刻只能被一个进程处理,以保证数据的一致性和准确性。

四、注意事项

1. 锁的过期时间

设置合理的锁过期时间非常重要。过短可能导致业务逻辑未完成时锁已失效,过长则可能导致死锁。可以通过 tryLock(long waitTime, long leaseTime, TimeUnit unit) 方法动态设置等待时间和锁持有时间。

boolean isLocked = lock.tryLock(5, 30, TimeUnit.SECONDS); // 最多等待5秒,锁持有时间为30秒
if (isLocked) {try {// 执行业务逻辑} finally {lock.unlock();}
}
2. 异常处理

在获取锁的过程中可能会抛出 InterruptedException,需要正确处理中断信号,避免线程处于不明确的状态。确保在 finally 块中释放锁,防止因为异常导致锁未释放。

try {boolean isLocked = lock.tryLock(5, 30, TimeUnit.SECONDS);if (isLocked) {// 执行业务逻辑}
} catch (InterruptedException e) {Thread.currentThread().interrupt();System.err.println("Thread was interrupted while trying to acquire lock.");
} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}
}
3. 网络分区问题

在 Redis 集群环境中,网络分区可能导致部分节点无法正常工作,影响锁的可靠性。使用 Redlock 算法可以在一定程度上缓解这个问题,但不能完全避免。

4. 序列化与反序列化

如果锁的值包含复杂对象,需注意序列化与反序列化的性能和兼容性问题。可以选择合适的序列化器,如 Jackson JSON 序列化器或 Kryo 序列化器。

config.setCodec(new JsonJacksonCodec()); // 设置Jackson JSON序列化器

五、完整示例代码

以下是一个结合上述要点的更完整的示例,展示了如何使用 Redisson 实现分布式锁,并考虑了异常处理和锁的自动续期。

1. 单机模式下的分布式锁
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonDistributedLockExample {public static void main(String[] args) {// 配置Redisson客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setCodec(new JsonJacksonCodec()); // 设置序列化器RedissonClient redisson = Redisson.create(config);String lockName = "myDistributedLock";RLock lock = redisson.getLock(lockName);try {// 尝试获取锁,最多等待5秒,锁持有时间为30秒boolean isLocked = lock.tryLock(5, 30, java.util.concurrent.TimeUnit.SECONDS);if (isLocked) {System.out.println("Lock acquired successfully.");performBusinessLogic();} else {System.out.println("Failed to acquire lock.");}} catch (InterruptedException e) {Thread.currentThread().interrupt();System.err.println("Thread was interrupted while trying to acquire lock.");} finally {// 确保最终释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();System.out.println("Lock released.");}}// 关闭Redisson客户端redisson.shutdown();}private static void performBusinessLogic() {System.out.println("Executing business logic...");try {// 模拟耗时操作Thread.sleep(10000); // 模拟10秒的操作} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}
2. 集群模式下的分布式锁(RedLock)
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.redisson.RedissonRedLock;public class RedissonRedLockExample {public static void main(String[] args) {// 配置Redisson客户端Config config = new Config();config.useClusterServers().addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:6380", "redis://127.0.0.1:6381");RedissonClient redisson = Redisson.create(config);RLock lock1 = redisson.getLock("lock1");RLock lock2 = redisson.getLock("lock2");RLock lock3 = redisson.getLock("lock3");RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);try {// 尝试获取锁,最多等待5秒,锁持有时间为30秒boolean isLocked = redLock.tryLock(5, 30, java.util.concurrent.TimeUnit.SECONDS);if (isLocked) {System.out.println("RedLock acquired successfully.");performBusinessLogic();} else {System.out.println("Failed to acquire RedLock.");}} catch (InterruptedException e) {Thread.currentThread().interrupt();System.err.println("Thread was interrupted while trying to acquire RedLock.");} finally {// 确保最终释放锁if (redLock.isLocked()) {redLock.unlock();System.out.println("RedLock released.");}}// 关闭Redisson客户端redisson.shutdown();}private static void performBusinessLogic() {System.out.println("Executing business logic with RedLock...");try {// 模拟耗时操作Thread.sleep(10000); // 模拟10秒的操作} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

六、最佳实践

1. 选择合适的锁类型

根据具体的业务需求选择合适的锁类型(如可重入锁、公平锁、联锁、红锁等)。例如,对于需要递归调用的方法,应使用可重入锁;对于多读少写的场景,应使用读写锁。

2. 合理设置锁的过期时间

锁的过期时间应根据业务逻辑的执行时间合理设置,避免锁超时或死锁问题。可以通过 tryLock(long waitTime, long leaseTime, TimeUnit unit) 方法动态设置等待时间和锁持有时间。

3. 正确处理异常

在获取锁的过程中捕获并处理可能的异常,确保锁能够被正确释放。尤其是在多线程环境下,务必确保锁的释放不会遗漏。

4. 使用序列化器

如果锁的值包含复杂对象,选择合适的序列化器以提高性能和兼容性。常见的序列化器包括 Jackson JSON 序列化器和 Kryo 序列化器。

5. 监控和日志

在生产环境中使用分布式锁时,建议添加适当的监控和日志记录,以便及时发现和解决潜在的问题。例如,记录每次获取锁的时间、锁的状态变化等信息。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com