クライアントリクエストのフローを処理したい。各リクエストには特別なタイプがあります。まず、そのタイプのデータを初期化する必要があります。その後、リクエストの処理を開始できます。クライアントタイプが初めて来るときは、対応するデータを初期化するだけです。この後、そのタイプの以下のすべてのリクエストは、そのデータを使用して処理されます。
これをスレッドセーフな方法で行う必要があります。
これが私が書いたコードです。スレッドセーフですか?
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は同じAに対してmap.put(A、B)== nullを2回生成できません。他方では、割り当てと比較の操作はスレッドセーフではありません。
それで、このコードは大丈夫ですか?そうでない場合、どうすれば修正できますか?
更新:Martin Serranoのコードはスレッドセーフであり、初期化の二重の問題が発生しにくいため、私はMartinSerranoの回答を受け入れました。ただし、私のバージョンでは問題が見つからず、以下の回答として投稿されており、私のバージョンでは同期が必要ないことに注意してください。