どのように動作させたいかによって、スレッドセーフになる場合とそうでない場合があります。
コードの最後までに、aMap
安全にRecord
for がありid
ます。ただし、2 つのスレッドが作成と挿入の両方Record
を行い、2 つ (またはそれ以上のスレッドが実行する場合はそれ以上)Records
が存在する可能性があります。それは問題ないかもしれませんし、そうではないかもしれません - 本当にあなたのアプリケーションに依存します。
スレッド セーフの危険性の 1 つ (たとえば、HashMap
同期なしで法線を使用する場合) は、スレッド間で部分的に作成または部分的に更新されたオブジェクトをスレッドが読み取ることができることです。言い換えれば、物事は本当に混乱する可能性があります。スレッド間でメモリが最新の状態に保たれるため、これはコードでは発生しません。その意味で、スレッドセーフです。ConcurrentHashMap
できることの 1 つは を使用することですputIfAbsent
。これは、キーと値のペアをアトミックにマップに配置しますが、そのキーにまだ何もない場合に限ります。
if (rec == null) {
records.putIfAbsent(id, new Record(id));
rec = records.get(id);
}
このアプローチでは、2 番目のRecord
オブジェクトを作成することもできますが、その場合、オブジェクトは挿入されず、すぐにガベージ コレクションに使用できるようになります。スニペットの終わりまでに:
records
指定されたRecord
ID の
Record
そのIDに入れられたのは1つだけrecords
です(このスレッドまたは別のスレッドによってそこに入れられたかどうかにかかわらず)
rec
そのレコードを指します