package com.aswatson.cdc.test;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config; import java.time.LocalDateTime;
import java.util.concurrent.*; /**
* boolean success = lock.tryLock(0, 0, TimeUnit.SECONDS); // 表示尝试获取锁,等待0秒,持有锁0秒钟
* 注意问题,存在的隐患: 虽然 tryLock(0, 0, TimeUnit.SECONDS)
*
* 首先1. 但实际锁的释放仍然会受到 Redisson 看门狗机制的影响。如果持有锁的线程未能在续约周期内续约锁的持有时间,那么锁可能会在超时后被自动释放。
* (默认是每隔 30 秒进行一次续约)来维持锁的有效性,避免因为持有锁的线程未能释放而造成锁的永久占用。或者自己unLock。
*
* 其次2. 确保你使用的 Redisson 版本与 Redis 版本兼容,并且不会因为版本问题导致锁的行为异常。目前测试用的是redis(2.7.17)、redisson(3.24.3)
*
* 其次3. 默认情况下,Redisson 的看门狗会定期发送续约请求给 Redis 服务器,以延长当前持有的锁的有效期。但是也有不会续约的可能性:
* Redis 连接中断、Redisson 配置问题、持有锁的线程崩溃、锁的最大持有时间到期。
*
* 其次4. 即使在业务逻辑中调用了阻塞操作(如 sleep),Redisson 也会在后台继续进行续约操作,以防止锁被意外释放。
*
*/
public class TestRedissonLeaveTimeLock { public static void main(String[] args) throws Exception { Config config = new Config();
config.useSingleServer().setAddress("redis://10.95.35.93:37495");
RedissonClient redissonClient = Redisson.create(config);
RLock lock = redissonClient.getLock("lockName");
System.out.println("创建好了RedissonClient" + getName()); int numThreads = 10;
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
CountDownLatch startLatch = new CountDownLatch(1);
CountDownLatch doneLatch = new CountDownLatch(numThreads); // 尽管 for 循环看起来是按顺序逐个,但实际上每个任务会并发地在后台执行。
// 这是因为每次调用 submit时,任务被提交给线程池,而线程池会根据可用的线程资源并发执行这些任务。
for (int i = 0; i < numThreads; i++) {
executor.submit(() -> {
try {
startLatch.await(); // 等待主线程的启动信号 System.out.println("获取锁前的时间:"+ getName());
boolean success = lock.tryLock(0, 0, TimeUnit.SECONDS); // 尝试获取锁,等待0秒,持有锁0秒钟
System.out.println("获取锁后的时间:"+ getName());
if (success) {
System.out.println("拿到锁"+ getName());
// 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
TimeUnit.SECONDS.sleep(20);
} else {
System.out.println("未能获取到锁,已放弃尝试" + getName());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
doneLatch.countDown();// 每次减去1 // 判断当前线程是否持有锁
if (lock.isHeldByCurrentThread()) {
System.out.println("释放锁"+ getName());
lock.unlock();
}
}
});
} System.out.println("主线程即将释放所有等待的线程...");
startLatch.countDown(); // 释放定义的1条线程,开始并发执行
doneLatch.await(); // 等待所有线程10条完成
executor.shutdown();
System.out.println("所有线程执行完成" + getName());
} public static String getName() {
return Thread.currentThread().getName() + "---" + LocalDateTime.now();
} }

记一个,生产遇到的redission锁,释放问题:lock.tryLock(0, 0, TimeUnit.SECONDS)的更多相关文章

  1. 深入浅出 Java Concurrency (9): 锁机制 part 4 锁释放与条件变量 (Lock.unlock And Condition)

    本小节介绍锁释放Lock.unlock(). Release/TryRelease unlock操作实际上就调用了AQS的release操作,释放持有的锁. public final boolean ...

  2. MySql一个生产死锁案例分析

    接到上级一个生产环境MySQL死锁日志信息文件,需要找出原因并解决问题.我将死锁日志部分贴出如下: 在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信 ...

  3. 如何创建一个简单的C++同步锁框架(译)

    翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...

  4. java 哪些情况下会使对象锁释放

    Java_多线程_锁释放 问:Java多线程运行环境中,在哪些情况下会使对象锁释放?答:由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的 ...

  5. 一个Redis实现的分布式锁

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.conne ...

  6. 从一个实例谈谈postgresql索引锁

    最近客户在使用我司开发的数据库时,报告了如下问题(也不能算是问题,就是疑惑吧),环境如下: OS : Red Hat Enterprise Linux Server release 6.7 (Sant ...

  7. 对象的notify方法的含义和对象锁释放的三种情况

    1,notify的含义     (1)notify一次只随机通知一个线程进行唤醒 (2)在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁, 要等到 ...

  8. 事务(进程 ID 64)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

    访问频率比较高的app接口,在后台写的异常日志会偶尔出现以下错误. 事务(进程 ID 64)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品.请重新运行该事务 实所有的死锁最深层的原因就是一个 ...

  9. 聊聊高并发(三十二)实现一个基于链表的无锁Set集合

    Set表示一种没有反复元素的集合类,在JDK里面有HashSet的实现,底层是基于HashMap来实现的.这里实现一个简化版本号的Set,有下面约束: 1. 基于链表实现.链表节点依照对象的hashC ...

  10. C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别

    C# 最基本的涉及模式(单例模式) //密封,保证不能继承 public sealed class Xiaohouye    { //私有的构造函数,保证外部不能实例化        private  ...

随机推荐

  1. vue中vant-list组件实现下拉刷新,上滑加载

    后端返回的数据是一股脑的情况(不是按pageSize,pageNum一组一组的发送)时,前端使用vant-list实现懒加载需要再写一点js,记录一下 main.js: Vue.use(List); ...

  2. ADOBE FORM的一些相关资料

    虽然很多人觉得打印程序的开发很无聊(我也这么想),但在实际工作中,打印算是比较有意义的工作,所以还是值得学习的. 之前翻译过几篇Adobe Form的文章,其中的内容,可以帮助创建一些简单的打印示例, ...

  3. 免费的visual studio智能代码插件——CodeGeeX

    CodeGeeX是什么?什么是CodeGeeX? CodeGeeX是一款基于大模型的智能编程助手,它可以实现代码的生成与补全,自动为代码添加注释,不同编程语言的代码间实现互译,针对技术和代码问题的智能 ...

  4. NumPy 数组切片及数据类型介绍

    NumPy 数组切片 NumPy 数组切片用于从数组中提取子集.它类似于 Python 中的列表切片,但支持多维数组. 一维数组切片 要从一维数组中提取子集,可以使用方括号 [] 并指定切片.切片由起 ...

  5. WEB服务与NGINX(19)- nginx 防盗链功能

    目录 1 nginx防盗链功能 1.1 盗链功能概述 1.2 实现盗链 1.3 实现防盗链 1 nginx防盗链功能 1.1 盗链功能概述 防盗链基于客户端携带的referer实现,referer是记 ...

  6. Docker打包程序镜像

    简介 做了一个视频检测程序,它是由golang和c++编写的.因为公司要做私有化部署,因此需要打包成镜像然后放到公司的registry镜像仓库里.之前一直没有去熟悉docker,现在刚好机会来了,咱就 ...

  7. console小知识

    console.log(JSON.stringify(object,null,2));

  8. 泊松盘采样(Poisson Disk Sampling)生成均匀随机点

    当需要生成随机点且要求随机点自然均匀的分布时,使用泊松盘采样就较为适合. 但该方法与统计学上的概念关联不大,这个只相当于点在面积上服从泊松分布, 而实现这个结果有很多做法. 最终效果: 圆形为含半径的 ...

  9. [Unity] 实现AssetBundle资源加载管理器

    实现Unity AssetBundle资源加载管理器 AssetBundle是实现资源热更新的重要功能,但Unity为其提供的API却十分基(jian)础(lou).像是自动加载依赖包.重复加载缓存. ...

  10. 排查Python卡慢神器

    如果遇到Python正在运行中的进程卡住,找不到原因.可以试试以下工具方法, 对于python就像jstack对于java一样. 法一 使用pystack-debugger 安装方式如下: yum i ...