I、文字列のマップのラッパーとして機能する略オブジェクト、使用しています。私がアクセスすると、上記フォーマッタはSimpleDateFormatのスレッドセーフではありません。
public class Formatter {
private static final NumberFormat NUMBER_FORMAT;
public BigDecimal formatNumber(String s) {
Number num = NUMBER_FORMAT.parse(s);
if (num instanceof Integer) {
return new BigDecimal((Integer) num);
} else if (num instanceof Double) {
return new BigDecimal((Double) num);
} ...
}
}
ためのマッパーとほぼ働く
public class Wrapper {
private Map<String, String> values;
private Formatter formatter;
public BigDecimal getSpecialValue() {
String result = values.get("Special");
return formatter.formatNumber(result);
}
}
を例えば、NumberFormatException
またはParseException
が存在し、解析された文字列が.430の代わりに.430.430であるなどのように、いくつかのスレッドは同時に複数のスレッドによって処理することができます。
興味を引く2つの側面があります。 1.)ラッパーは読み取り専用でアクセスされます。コレクションへのアクセスは同期されていませんが、これは常に機能するはずです。 2)問題を見つける最初の試みの1つで、formatNumber
メソッド(明らかにシングルスレッド)を実行するようにWrapper
クラスのコンストラクタを変更しました。これにより、すべての例外が実行されなくなりました。
誰かが説明できますか?
編集: Wrapper
クラスのマップは、最も確実にシングルスレッドのコンストラクタで埋められます。その後、マップは不変であるようにラッパーが設計されます。ただ、「スレッド」のためjdocを検索
、ThreadLocalの<のNumberFormat> – Nate
@Nateうん明白な解決策を使用します(と私が今まで 'ThreadLocal'使用するのは初めてだろう! - エキゾチックなもののためにプラスのポイントを提供します)。それはアクセス頻度などによって異なりますが、スレッドを一度しか使用しない場合、スレッドごとに新しいインスタンスを作成すると、一部のロックよりも効率が低下する可能性があります。 – Voo
理解して受け入れます。私はjavadocを読んでいませんでしたが、私はNumberFormat(および子クラス)ソースコードをブラウズしていましたが、NumberFormatがスレッドセーフでない理由を説明できるメンバ変数を検出しませんでした。そのメンバ変数が読取り専用でアクセスされても、クラスはスレッドセーフではありませんか? – Jonathan