- - PR -
parse時にNumberFormatExceptionが発生する
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-07-09 10:19
DateFormatとそのサブクラス(SimpleDateFormat等)スレッドセーフではありません。
JDK1.4の場合、parseの途中経過とformatの処理対象日付を、同一のインスタンス変数に保持するという、スレッドセーフを一切考慮していない実装が行われています。 これがどれほど危険なことかわかりますよね。 | ||||||||
|
投稿日時: 2008-07-09 10:30
>nagiseさん
ご指摘ありがとうございます。 質問させてください。
これは public boolean valid(String date) {} で宣言する と認識しております。 一方、教えていただいた 「SimpleDateFormatでNumberFormatException 」のページよりリンクしている 「java.text.SimpleDateFormat はスレッドセーフではない 」を参照すると synchronized宣言で囲むことを対処方法としており public static synchronized boolean valid(String date) {} で宣言する と認識しております。 また、デメリットとしては 前者は、メモリの消費 後者は、待ち時間の発生 が考えられると認識しております。 この場合、どちらがより良い対処方法になるのでしょうか? また、認識違いがありましたらご指摘下さい。 | ||||||||
|
投稿日時: 2008-07-09 10:59
わかります。 危険ですね。 不可解な現象が多いわけです。 (わかってしまえば不可解ではありませんが・・・) | ||||||||
|
投稿日時: 2008-07-09 13:26
都度生成しても、メモリはGCによって解放されますので、 あまり気にするポイントではありません。 インスタンスの生成コストくらいでしょうか。 WEBのように複数スレッドによる参照が発生する場合、 同期コストの方が問題となります。 同期コストをかけずに、かつインスタンス生成を減らす方法としては、 スレッドローカルを使うという方法も有ります。
SimpleDateFormatのインスタンスはスレッド毎に生成されますが、 同一スレッドにおいてすでに生成済みであれば、それ以降は生成されません。 | ||||||||
|
投稿日時: 2008-07-09 14:30
「SimpleDateFormatでNumberFormatException 」のコメント欄での議論がありますが、かつのりさん調べによれば少なくともインスタンスが別であれば問題がないという結論ですね。 「java.text.SimpleDateFormat はスレッドセーフではない」で書かれているように、唯一のスレッドからしか使わないとまでする必要はないようです。 ですから、
あたりの対処法が無難でしょうか。 synchronizedによる同期はロックが発生するのであまり好ましくないように思います。パースのたびにロックするとしたら、回数も尋常ではないでしょうし。 世代の短いオブジェクトのGCは高速なのでメモリについてはそれほど心配することはありません。 SimpleDateFormatだとオブジェクトの生成コストがやや高いような気もしますが、全体のパフォーマンスにクリティカルに影響するようなものではないでしょう。このあたりは実測してみないとなんとも言えませんが。 それでも気になるならThreadLocalでオブジェクトを使いまわすようにしておけばいいのではないでしょうか。サンプルはかつのりさんが提示していますね。 | ||||||||
|
投稿日時: 2008-07-10 13:20
かつのりさん
nagiseさん 回答ありがとうございます。 ご意見、とても参考になります。 まずSimpleDateFormatのインスタンスを使い捨てにする対処を行い 実測の結果問題があるようなら ThreadLocalを使用する方法に転換したいと考えています。 ありがとうございました。 | ||||||||
|
投稿日時: 2008-07-10 17:14
これはそのページの、みなさんのコメントまで含めて読む必要があるわけですね。 最初、コメントをすっ飛ばして本体だけ読んでいて、ええっ、と思ってしまいました。 | ||||||||
|
投稿日時: 2008-07-10 18:15
うーむ。こういう時にさっと提示できるようにちゃんとまとめたエントリにしておいた方がいいですね…。下手に読ませると逆に誤解を招くかもしれないですねぇ。 |