想要的效果:lock(name, 30s) name 是变量,后边是自动失效时间 不知道有没有类似的成熟库
|      1golangLover      2022-06-07 18:50:22 +08:00 via Android  4 guava cache | 
|      2sulinwork      2022-06-07 19:26:13 +08:00  2 都是本地了 为何不直接用 JDK 自带的 Lock 或者 synchronized | 
|  |      3displayabc OP @sulinwork 你肯定没看懂我说什么。。。 | 
|  |      4potatowish      2022-06-07 21:35:31 +08:00 via iPhone 可以尝试用 Semaphore 信号量和 DelayQueue 延迟队列自己封装一个 | 
|  |      5nl101531      2022-06-07 22:01:14 +08:00 本地锁一般没必要加超时时间,使用完就释放了,没使用完一直持久就好了,所以没怎么见到过你这种需求。 redis 之所以有超时,是分布式带来的不确定性。 | 
|  |      6mosliu      2022-06-07 22:37:16 +08:00 1L 说的应该是对的 记得是用过 | 
|  |      7b1t      2022-06-07 23:24:38 +08:00 本地缓存? | 
|      8rowe      2022-06-08 00:43:53 +08:00 redis 加过期时间是因为 在分布式环境加锁风险太大 redis 给出兜底的方案, 单应用加锁随便玩好吗 | 
|  |      9chendy      2022-06-08 07:49:18 +08:00 Map<String, Lock>  超时感觉没必要,都写 finally 里了 redis 超时是怕客户端抽了不释放锁,单机环境没有这个问题 | 
|  |      10wanguorui123      2022-06-08 08:38:12 +08:00 自旋锁 | 
|      12qocja      2022-06-08 09:33:38 +08:00 如果你想要锁值的 参考这个文章 | 
|      13qocja      2022-06-08 09:33:46 +08:00  1 | 
|      14huangz003      2022-06-08 09:41:17 +08:00 caffeine > guava cache caffeine 是基于 guava cache 开发的,可以构建过期策略,如超时,设置容量大小等方式 | 
|      15nothingistrue      2022-06-08 10:26:08 +08:00 你是想用缓存,还是要线程加锁,还是要利用定时自动解锁做业务逻辑。如果是线程加锁的话,用 await 、wait 、notify 这些线程通信机制来解锁会更有效,实在不行,你还可以用 sleep 。如果是另外两个场景,用 Redis ,比自己搞,更简单还更可靠。 | 
|  |      16nekoneko      2022-06-08 10:29:47 +08:00  2 synchronized(name.intern()) 单应用不需要过期时间 | 
|  |      17displayabc OP @nekoneko 还是你这个让人想不到。。。 | 
|      18ZeawinL      2022-06-08 11:15:20 +08:00 #16 楼的方案挺好 | 
|      19ZeawinL      2022-06-08 11:19:36 +08:00 或许也可以使用 ConcurrentHashMap 结合 ReentrantLock 实现. ``` Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>(); ReentrantLock lock = lockMap.getOrDefault("key-name", new ReentrantLock()); lock.tryLock(1, TimeUnit.SECONDS); ``` 会不会有什么问题? 坐等大佬指出 | 
|      20ZeawinL      2022-06-08 11:34:33 +08:00  1 纠正一下 #19 ``` Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>(); ReentrantLock lock = lockMap.computeIfAbsent("key-name", l -> new ReentrantLock()); lock.tryLock(1, TimeUnit.SECONDS); ``` | 
|  |      21potatowish      2022-06-08 12:20:33 +08:00 via iPhone  1 @ZeawinL 时间参数是最大等待锁的时间,不是最大持有时间啊 | 
|  |      22RedBeanIce      2022-06-08 12:29:51 +08:00 via iPhone 2l 是对的。 | 
|  |      23displayabc OP @ZeawinL 锁什么时候释放,Map 什么时候清除这个 key 姑且按 lockMap.remove("key-name"); lock.unlock(); 这种来处理 当第一个线程 remove 操作之前,有第二个线程来获取锁,获取的还是老的 ReentrantLock ,在 tryLock 阶段,第一个线程 remove 操作了,第三个线程来获取锁,肯定是新的 ReentrantLock | 
|      24ZeawinL      2022-06-08 13:36:57 +08:00 via iPhone @potatowish 理解错了,感谢指正 | 
|      25mrsatangel      2022-06-08 18:16:38 +08:00  2 | 
|  |      26potatowish      2022-06-08 22:27:59 +08:00 via iPhone 用字符串变量作为锁的名称没有太难吧,用 ConcurrentHashMap 映射一下,或者直接用 intern ,获取常量池引用。 我觉得重点应该是如何实现锁的过期机制,有没有必要可先放一边。 | 
|  |      27NULL2020      2022-07-21 11:01:18 +08:00 所以,OP 最后使用了什么方法? | 
|  |      28displayabc OP |