синхронизированный имеет плохую производительность

имеет удобную функцию:

SELECT GET_LOCK("SomeName")

Это можно использовать для создания простых, но очень специфичных блокировок на основе имен для приложения. Однако для этого требуется подключение к базе данных.

У меня много ситуаций, таких как:

someMethod() {
    // do stuff to user A for their data for feature X
}

Не имеет смысла просто синхронизировать этот метод, потому что, например, если этот метод вызывается для пользователя B в то же время, пользователю B не нужно ждать, пока пользователь A завершит работу, прежде чем он начнет, только операции для пользователя А и функцию Х-комбинацию нужно подождать.

С блокировкой MySql я мог бы сделать что-то вроде:

someMethod() {
    executeQuery("SELECT GET_LOCK('userA-featureX')")
    // only locked for user A for their data for feature X
    executeQuery("SELECT RELEASE_LOCK('userA-featureX')")
}

Поскольку блокировка Java основана на объектах, мне кажется, что мне нужно создать новый объект, чтобы представить ситуацию для этой блокировки, а затем поместить ее в статический кеш где-нибудь, чтобы все потоки могли его увидеть. Последующие запросы на блокировку для этой ситуации затем находят объект блокировки в кэше и получают его блокировку. Я пытался создать что-то подобное, но затем сам кэш блокировки нуждается в синхронизации. Кроме того, трудно определить, когда объект блокировки больше не используется, чтобы его можно было удалить из кэша.

Я посмотрел на параллельные пакеты Java, но ничто не выделяется возможностью обрабатывать что-то подобное. Есть ли простой способ реализовать это, или я смотрю на это с неправильной точки зрения?

Редактировать:

Чтобы уточнить, я не собираюсь заранее создавать предопределенный пул блокировок, я хотел бы создавать их по требованию. Некоторый псевдокод для того, что я думаю:

LockManager.acquireLock(String name) {
    Lock lock;  

    synchronized (map) {
        lock = map.get(name);

        // doesn't exist yet - create and store
        if(lock == null) {
            lock = new Lock();
            map.put(name, lock);
        }
    }

    lock.lock();
}

LockManager.releaseLock(String name) {
    // unlock
    // if this was the last hold on the lock, remove it from the cache
}

Ответы на вопрос(22)

Ваш ответ на вопрос