Я хочу обработать поток клиентских запросов. Каждый запрос имеет свой особый тип. Сначала мне нужно инициализировать некоторые данные для этого типа, и после этого я могу начать обрабатывать запросы. Когда тип клиента приходит впервые, я просто инициализирую соответствующие данные. После этого все последующие запросы этого типа обрабатываются с использованием этих данных.
Мне нужно сделать это потокобезопасным способом.
Вот код, который я написал. Является ли он потокобезопасным?
public class Test {
private static Map<Integer, Object> clientTypesInitiated = new ConcurrentHashMap<Integer, Object>();
/* to process client request we need to
create corresponding client type data.
on the first signal we create that data,
on the second - we process the request*/
void onClientRequestReceived(int clientTypeIndex) {
if (clientTypesInitiated.put(clientTypeIndex, "") == null) {
//new client type index arrived, this type was never processed
//process data for that client type and put it into the map of types
Object clientTypeData = createClientTypeData(clientTypeIndex);
clientTypesInitiated.put(clientTypeIndex, clientTypeData);
} else {
//already existing index - we already have results and we can use them
processClientUsingClientTypeData(clientTypesInitiated.get(clientTypeIndex));
}
}
Object createClientTypeData(int clientIndex) {return new Object();}
void processClientUsingClientTypeData(Object clientTypeData) {}
}
С одной стороны, ConcurrentHashMap не может создать map.put(A,B) == null два раза для одного и того же A. С другой стороны, операция присваивания и сравнения не является потокобезопасной.
Так этот код в порядке? Если нет, то как я могу это исправить?
ОБНОВЛЕНИЕ: я принял ответ Мартина Серрано, потому что его код является потокобезопасным и не подвержен проблемам с двойной инициализацией. Но я хотел бы отметить, что я не обнаружил проблем с моей версией, опубликованной в качестве ответа ниже, и моя версия не требует синхронизации.