Peter Lawryのブログhereにこのコードが見つかりました。彼は、このクラスはそれ以上の同期を必要としないと述べている。同期なしでデータを共有する - このコードはスレッドセーフですか?
私は同時性に関する知識と不要な同期を回避する方法を改善しようとしていますので、このケースについてJavaメモリモデルの観点から推論する方法を考えようとしています。
文字列配列への参照が最終的なもので、文字列自体は不変ですが、配列に含まれる文字列への参照が変更可能です
- は、あるスレッドがまだ見ることができること、それは、少なくとも理論的には可能ではありません別のスレッドが値を更新した後はnullですか?
- 文字列が複数回使用されている場合は気にしませんか?
また、JVMには、私が紛失しているという追加の保証がありますか?あなたのケースでは
public class StringInterner { private final String[] interner; private final int mask; public StringInterner(int capacity) { int n = Maths.nextPower2(capacity, 128); interner = new String[n]; mask = n - 1; } private static boolean isEqual(@Nullable CharSequence s, @NotNull CharSequence cs) { if (s == null) return false; if (s.length() != cs.length()) return false; for (int i = 0; i < cs.length(); i++) if (s.charAt(i) != cs.charAt(i)) return false; return true; } @NotNull public String intern(@NotNull CharSequence cs) { long hash = 0; for (int i = 0; i < cs.length(); i++) hash = 57 * hash + cs.charAt(i); int h = (int) Maths.hash(hash) & mask; String s = interner[h]; if (isEqual(s, cs)) return s; String s2 = cs.toString(); return interner[h] = s2; } }
注意を並列実行固有ではありません。これは、複数の文字列が同じバケットにハッシュする可能性があるためです。 – gudok
@gudok:はい、それは本当です。私はただの視点から見ていただけだった。私は答えにそれを追加します – Sorontur
@Sorontur - あなたの答えをありがとう、確認するために、スレッドが別のスレッドの後に文字列(nullまたは以前に格納された値)の古い値を見ることができると推論するのは正しいですか?そのメモリ位置に文字列を格納していますか? - シェーン50分前 – Shane