У меня приложение Java без сохранения состояния, развернутое на веб-сервере Tomcat. Из-за характера данных в любой момент времени все http-потоки должны обрабатывать разные ключи (другими словами: все потоки должны обрабатывать разные ключи).
Следовательно, я написал модуль, который ставит в очередь сообщение http, если ключ запроса находится в процессе выполнения (сообщением http до этого). Я продолжу обрабатывать текущую запись http только после завершения предыдущей записи http с тем же ключом.
Я написал простой цикл while с concurrenthashmap, чтобы проверить, выполняется ли какой-либо предыдущий запрос с тем же ключом. Производительность ниже номинальной и наблюдается непредвиденное поведение. Это фрагмент кода:
//This part of code is place inside the servlet
private static ConcurrentHashMap<String, String> transQueue = new ConcurrentHashMap<String, String>();
private void inQueuePoll(String queueKey) {
while(transQueue.containsKey(queueKey)){
synchronized(this){
try{
Thread.sleep(50); // i know this is bad, any idea to improve this?
logger.trace("Wait for Que Key: "+queueKey + " );
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
transQueue.put(queueKey, "");
}
В конце каждого http-сообщения, в блоке finally, я помещаю: transQueue.remove (queueKey), чтобы убедиться, что я удалил его из таблицы concurrenthashmap. Тем не менее, в своем худшем кошмаре из журнала сервера я заметил, что перед удалением queueKey, еще одной нити HTTP-поста, удается выйти из цикла while и продолжить обработку.
Что-то я сделал неправильно в приведенном выше коде, чтобы "поставить в очередь" поток http?
Также очень ценится любая идея о том, как я могу сделать это лучше.