首页 > 解决方案 > Java 同步取决于方法参数

问题描述

如何在方法参数值上提供同步?

所有使用“相同”参数值 A 的方法调用都应该同步。具有不同参数值的方法调用(例如 B)可以访问,即使使用 A 的调用已经在等待。对 B 的下一个并发调用也必须等待第一个 B 被释放。

我的用例:我想在 ID 级别同步对 JPA 实体的访问,但想避免悲观锁定,因为我需要某种队列。用于锁定的“键”是实体 ID - 实际上是 Java Long 类型。

protected void entityLockedAccess(SomeEntity myEntity) {
    //getId() returns different Long objects so the lock does not work
    synchronized (myEntity.getId()) {
        //the critical section ...
    }
}

我阅读了有关锁定对象的信息,但我不确定它们如何适合我的情况。在顶层,我想管理对执行关键代码的应用程序的特定 REST 调用。

谢谢,克里斯

标签: javarestsynchronizationsynchronized

解决方案


据我了解,您基本上希望每个SomeEntityID 都有一个不同的、唯一的锁。

您可以通过Map<Integer, Object>.

您只需将每个 ID 映射到一个对象。如果已经有一个对象,您可以重用它。这可能看起来像这样:

static Map<Integer, Object> locks = new ConcurrentHashMap<>();

public static void main(String[] args)
{
    int i1 = 1;
    int i2 = 2;

    foo(i1);
    foo(i1);
    foo(i2);
}

public static void foo(int o)
{
    synchronized (locks.computeIfAbsent(o, k -> new Object()))
    {
        // computation
    }
}

这将在映射中创建 2 个锁定对象,因为该对象在第二次调用中i1被重用。foo(i1)


推荐阅读