ThreadLocalマルチスレッド問題の解決

1755 ワード

クライアントだけでなく、サーバ側でも同様の問題があり、servletはマルチスレッドであり、呼び出しバックグラウンドのserviceレイヤもマルチスレッドであり、serviceレイヤで静的であるか、単一例のメンバー変数でマルチスレッドセキュリティの問題がある場合、SimpleDataFormatのように取得した日付エラーが発生します.
---------------------------------
log-servicesプロジェクトで異なるipからマルチスレッドでダウンロードすると、解析ログに異常が発生します.
SimpleDataFormat parseを使用すると、NumberFormatException:For input string:""が表示されます.
理由はSimpleDataFormatが非スレッドで安全であるため、私のコードのCommonServiceクラスではメンバー変数として使用されています.ソースコードのSimpleDataFormatはDateFormatのサブクラスであり、DateFormatではCalendarが定義されており、SimpleDataFormatにset(...)があります.get(...)メソッド、スレッドは安全ではありません.
リファレンス
http://stackoverflow.com/questions/4021151/java-dateformat-is-not-threadsafe-what-does-this-leads-to
DateFormat exposes a calendar field of type Calendar, and looking at the code of SimpleDateFormat, some methods call calendar.set(...) and others call calendar.get(...). This is clearly not thread-safe.

解決策
1,SimpleDataFormatを使用しないメンバー変数をゼロ時変数に変更
2 SimpleDataFormatを使用するすべての場所にsynchronizedを追加
3、ThreadLocalを使う
ThreadLocalの使用を推奨

public class DateFormatTest {

  private static final ThreadLocal<DateFormat> df
                 = new ThreadLocal<DateFormat>(){
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyyMMdd");
    }
  };

  public Date convert(String source)
                     throws ParseException{
    Date d = df.get().parse(source);
    return d;
  }
}