【问题标题】:Flexible alternatives for locking (selective lock)锁定的灵活替代方案(选择性锁定)
【发布时间】:2018-11-09 05:43:01
【问题描述】:

我需要解决具有不同内存位置的相同对象的情况(由于多线程,它发生在 REST 请求中)。

因此,作为部分解决方案,我实施了服务。我在这里分享最重要的部分:

private Map<T, ReentrantLock> lockHolder = new HashMap();

void unLock(T monitorMarker) {
    synchronized (lockHolder) {
        ReentrantLock lock = lockHolder.get(monitorMarker);
        if (lock == null || lock.getHoldCount() == 0) {
            return;
        }
        lock.unlock();
        if (lock.getHoldCount() == 0) {
            lockHolder.remove(monitorMarker);
        }
    }
}

ReentrantLock getLockForCalendar(T monitorMarker) {
    synchronized(monitorMarker) {
        ReentrantLock lock = lockHolder.get(monitorMarker);
        if (lock == null) {
            lock = new ReentrantLock();
            lockHolder.put(monitorMarker, lock);
        }
        return lock;
    }
}

一般来说它没有问题。

现在我需要将此实用程序映射到域元数据(解决方案可能是使用Map&lt;String, Map&lt;Object, Lock&gt;&gt; 或缓存注入,没有什么无法解决的)...

我更喜欢使用具有类似解决方案的 JDK util 或开源 util,因为它们已经提供了处理这种情况的功能......我相信很多开发人员面临类似的问题,并且开源库中应该存在解决方案。我研究了spring 实用程序,apache 实用程序一些google 库,但我没有找到满意的结果。

请建议我考虑使用正确的库。

【问题讨论】:

  • Re,“我需要解决具有不同内存位置的相同对象的情况。”为什么?您是否确定了偶尔为两个不同但相等的数据对象使用同一个锁对象的实际成本?而且,您是否确定您的应用程序无法承受的成本太高?
  • @jameslarge。这使得应用程序压力稳定。 QA 提供了一些案例,其中我的 REST 同时收到针对具有相同地下室的不同实体的两个不同的补丁请求。我知道我应该用乐观锁定来处理它,但情况不允许我添加模型更改(我之前写过相同的实体基础但不同的​​自定义实体部分)。所以我认为现在最适合同步的解决方法,但我希望我会在生产后处理它:)。
  • 您的意思是您想要ab 的不同锁,其中a.equals(b)a != b?还是你想要同样的锁?
  • @Kayaman 对于a.equals(b)a != b 的情况应该是同一个锁
  • 等等,这些锁保护了哪些数据?是ab 对象本身吗?但是如果这些对象需要保护,那么这意味着它们是可变的。改变对象会改变相等关系吗? (具有可变键的 HashMap 通常是一件坏事!)

标签: java multithreading concurrency locking


【解决方案1】:

Guava 的 Striped lock 实现可以完成您正在做的事情,但是正确(并且在弱锁、惰性、信号量而不是锁等方面有更多选择)。

这与您所做的并没有什么不同,但是您将 synchronized 与锁相结合,而 ConcurrentHashMap 可以摆脱显式同步(并且通过不每次都锁定整个地图来提供一些性能优势访问时间)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多