Java synchronization depending on method parameter

theFriedC :

how can I provide synchronization upon method parameter values?

All method calls using the 'same' parameter value A should be synchronized. A method call with a different parameter value e.g. B can access, even when calls with A are already waiting. The next concurrent call for B must wait also for the first B to be released.

My use case: I want to synchronize the access to JPA entities on ID level but want to avoid pessimistic locking because I need kind of a queue. The 'key' for locking is intended to be the entity ID - which is in fact of the type Java Long.

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

I read about lock objects but I am not sure how they would suit in my case. On the top level I want to manage a specific REST call to my application which executes critical code.

Thanks, Chris

Ben :

As far as I understood you basically want a different, unique lock for each of your SomeEntity IDs.

You could realize this with a Map<Integer, Object>.

You simply map each ID to an object. Should there already be an object, you reuse it. This could look something like this:

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
    }
}

This will create 2 lock objects in the map as the object for i1 is reused in the second foo(i1) call.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=86654&siteId=1