Java concurency - пул потоков - несколько запросов и пользователей - PullRequest
0 голосов
/ 29 ноября 2018

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

проблема в том, что количество запросов должно быть ограничено

Из чегоЯ понял, что в этом примере пул потоков должен работать нормально, но как насчет очереди блокировки?Не думаете ли вы, что должно быть лучшее решение?

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

Есть ли определенные решения для такой проблемы?

1 Ответ

0 голосов
/ 29 ноября 2018

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

Документация семафора: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html

Я бы использовал только один семафор, поэтому количество разрешений в семафоре будет фактически равно максимальному количеству соединений, разрешенных в системе.

Что касается количества подключений на пользователя, я бы сохранил счетчики пользовательских подключений в ConcurrentHashMap в реализации семафора, а затем настроил

public boolean tryAcquire(long timeout, TimeUnit unit, Long userId)
    throws InterruptedException {
    AtomicLong connCount = userConnetctionMap.contains(userId) ? userConnetctionMap.get(userId) :  userConnetctionMap.put(userId, new AtomicLong(0));
    if (connCount.get() < MAX_USER_CONN_COUNT) {
        boolean locked = super.tryAcquire(timeout, unit);
        if (locked) {
            userConnetctionMap.get(userId).incrementAndGet();
            return true;
        }
    }
    return false;
}

, чтобы увеличить счетчик на идентификатор пользователя, если его числозначение conn меньше максимально допустимого

и настраиваемое действие:

releaseUSerConnection(userId)

уменьшит значение этого счетчика

...