Java同步取决于方法参数

the*_*edC 2 java rest synchronization synchronized

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

使用“相同”参数值A的所有方法调用都应该同步。即使使用A的调用已在等待中,也可以访问具有不同参数值的方法调用,例如B。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 ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢克里斯

Ben*_*Ben 5

据我了解,您基本上希望为每个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
    }
}
Run Code Online (Sandbox Code Playgroud)

这将在地图中创建2个锁定对象,因为该对象将i1在第二个foo(i1)调用中重复使用。

  • 为了避免映射随着时间的推移而增加,将锁作为同步块内的最后一条语句删除是否安全?乍一看似乎没问题,但试图弄清楚我是否遗漏了一些东西。 (2认同)