displayabc
V2EX  ›  Java

Java 有类似于 Redis 锁的,只在本应用的锁吗?

  •  
  •   displayabc · Jun 7, 2022 · 5623 views
    This topic created in 1455 days ago, the information mentioned may be changed or developed.

    想要的效果:lock(name, 30s) name 是变量,后边是自动失效时间 不知道有没有类似的成熟库

    Supplement 1  ·  Jun 8, 2022
    感谢大家,目前看到这种方式最简单,也能实现类似效果
    synchronized (name.tostring().intern()) {
    ..
    }
    Supplement 2  ·  Jun 8, 2022
    使用 intern 这种形式,会有个问题,会导致 String 常量池迅速增大,造成性能下降,目前看到的资料是这个常量池很难回收
    28 replies    2022-07-21 15:33:54 +08:00
    golangLover
        1
    golangLover  
       Jun 7, 2022 via Android   ❤️ 4
    guava cache
    sulinwork
        2
    sulinwork  
       Jun 7, 2022   ❤️ 2
    都是本地了 为何不直接用 JDK 自带的 Lock 或者 synchronized
    displayabc
        3
    displayabc  
    OP
       Jun 7, 2022
    @sulinwork 你肯定没看懂我说什么。。。
    potatowish
        4
    potatowish  
       Jun 7, 2022 via iPhone
    可以尝试用 Semaphore 信号量和 DelayQueue 延迟队列自己封装一个
    nl101531
        5
    nl101531  
       Jun 7, 2022
    本地锁一般没必要加超时时间,使用完就释放了,没使用完一直持久就好了,所以没怎么见到过你这种需求。

    redis 之所以有超时,是分布式带来的不确定性。
    mosliu
        6
    mosliu  
       Jun 7, 2022
    1L 说的应该是对的 记得是用过
    b1t
        7
    b1t  
       Jun 7, 2022
    本地缓存?
    rowe
        8
    rowe  
       Jun 8, 2022
    redis 加过期时间是因为 在分布式环境加锁风险太大 redis 给出兜底的方案, 单应用加锁随便玩好吗
    chendy
        9
    chendy  
       Jun 8, 2022
    Map<String, Lock>
    超时感觉没必要,都写 finally 里了
    redis 超时是怕客户端抽了不释放锁,单机环境没有这个问题
    wanguorui123
        10
    wanguorui123  
       Jun 8, 2022
    自旋锁
    mosliu
        11
    mosliu  
       Jun 8, 2022   ❤️ 1
    查了下 当时用的
    caffeine 可以 expire
    @haython
    qocja
        12
    qocja  
       Jun 8, 2022
    如果你想要锁值的 参考这个文章
    huangz003
        14
    huangz003  
       Jun 8, 2022
    caffeine > guava cache
    caffeine 是基于 guava cache 开发的,可以构建过期策略,如超时,设置容量大小等方式
    nothingistrue
        15
    nothingistrue  
       Jun 8, 2022
    你是想用缓存,还是要线程加锁,还是要利用定时自动解锁做业务逻辑。如果是线程加锁的话,用 await 、wait 、notify 这些线程通信机制来解锁会更有效,实在不行,你还可以用 sleep 。如果是另外两个场景,用 Redis ,比自己搞,更简单还更可靠。
    nekoneko
        16
    nekoneko  
       Jun 8, 2022   ❤️ 2
    synchronized(name.intern())
    单应用不需要过期时间
    displayabc
        17
    displayabc  
    OP
       Jun 8, 2022
    @nekoneko 还是你这个让人想不到。。。
    tty0
        18
    tty0  
       Jun 8, 2022
    #16 楼的方案挺好
    tty0
        19
    tty0  
       Jun 8, 2022
    或许也可以使用 ConcurrentHashMap 结合 ReentrantLock 实现.

    ```
    Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
    ReentrantLock lock = lockMap.getOrDefault("key-name", new ReentrantLock());
    lock.tryLock(1, TimeUnit.SECONDS);
    ```

    会不会有什么问题? 坐等大佬指出
    tty0
        20
    tty0  
       Jun 8, 2022   ❤️ 1
    纠正一下 #19

    ```
    Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
    ReentrantLock lock = lockMap.computeIfAbsent("key-name", l -> new ReentrantLock());
    lock.tryLock(1, TimeUnit.SECONDS);
    ```
    potatowish
        21
    potatowish  
       Jun 8, 2022 via iPhone   ❤️ 1
    @ZeawinL 时间参数是最大等待锁的时间,不是最大持有时间啊
    RedBeanIce
        22
    RedBeanIce  
       Jun 8, 2022 via iPhone
    2l 是对的。
    displayabc
        23
    displayabc  
    OP
       Jun 8, 2022
    @ZeawinL 锁什么时候释放,Map 什么时候清除这个 key
    姑且按
    lockMap.remove("key-name");
    lock.unlock();
    这种来处理
    当第一个线程 remove 操作之前,有第二个线程来获取锁,获取的还是老的 ReentrantLock ,在 tryLock 阶段,第一个线程 remove 操作了,第三个线程来获取锁,肯定是新的 ReentrantLock
    tty0
        24
    tty0  
       Jun 8, 2022 via iPhone
    @potatowish 理解错了,感谢指正
    potatowish
        26
    potatowish  
       Jun 8, 2022 via iPhone
    用字符串变量作为锁的名称没有太难吧,用 ConcurrentHashMap 映射一下,或者直接用 intern ,获取常量池引用。

    我觉得重点应该是如何实现锁的过期机制,有没有必要可先放一边。
    NULL2020
        27
    NULL2020  
       Jul 21, 2022
    所以,OP 最后使用了什么方法?
    displayabc
        28
    displayabc  
    OP
       Jul 21, 2022
    @NULL2020
    synchronized (name.tostring().intern()) {
    ..
    }

    一是因为我的业务可以确定不会有太多字符串,二是可能还没等到常量池太大,就又重新部署一次了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5410 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 09:23 · PVG 17:23 · LAX 02:23 · JFK 05:23
    ♥ Do have faith in what you're doing.