どのように動作させたいかによって、スレッドセーフになる場合とそうでない場合があります。
コードの最後までに、aMap安全にRecordfor があり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指定されたRecordID の
RecordそのIDに入れられたのは1つだけrecordsです(このスレッドまたは別のスレッドによってそこに入れられたかどうかにかかわらず)
recそのレコードを指します