[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 1494] Java スレッドプロ グラミングを読む会第 2 回議事録



秋元です。はじめまして

今回、newsで案内を拝見して、初めて読書会に参加させていただきました。

日頃、どうもスレッドまわりをちゃんと理解してないし、どのように設計
するのが望ましいかという知識も足りないと思っていたのですが、独習す
る根気もなく、読書会という形式に期待してやってきました。

結果は大満足で、読んだ部分については身についたと思います。たぶん。
みなさんとの情報交換も為になりました。あまりお話できなかった方も
いますが、次回ぜひお話しましょう。

今後も可能な限り参加したいと思います。よろしくおねがいします。

"TAKEKAWA, Tsutomu" wrote:
> KJava スレッドプログラミング を読む会  第2回
> 
> ---------------------------------------------------------------
> 昼休み 11:50 - 12:55
>  java.text.SimpleDateFormatは、スレッドセーフではない。

余談のところだけコメントして何ですが、これは僕の発言です。

資料を末尾につけます。つっこみ大歓迎です。続くようでしたら
サブジェクトを変えてください。
-- 
Akky (AKIMOTO, Hiroki)
2nd Middleware Development Dept. NCS Div. PFU Ltd. Tokyo

===================================================================
java.text.SimpleDateFormat はスレッドセーフではない

[現象]
  複数のスレッドからformat()やparse()を使うと、おかしな結果になる
  ことがある

SunのBug Paradeを、"+SimpleDateFormat +thread"で検索してもらうとすぐ
わかるように、SimpleDateFormatクラスは、複数のインスタンスで同じオブ
ジェクトを共有して持っており、スレッドセーフではない。

http://developer.java.sun.com/developer/bugParade/bugs/4093418.html
http://developer.java.sun.com/developer/bugParade/bugs/4146524.html
http://developer.java.sun.com/developer/bugParade/bugs/4175308.html
http://developer.java.sun.com/developer/bugParade/bugs/4229798.html
http://developer.java.sun.com/developer/bugParade/bugs/4228335.html

これらのバグレポートの解説を総合すると、スレッドセーフにするには、
- format()やparse()を使うところを、 synchronized 宣言で囲む
- 独自のDateFormatを実装する
- 唯一のスレッドからしか、SimpleDateFormatが使われない作りにする
のいずれかしかないという結論になる。

上の処置を行わない場合の影響としては、
- format()した結果の日付時刻が、*たまーに*意図した通りにならない
- 4093418にあるように、*たまーに*StringIndexOutOfBoundsExceptions
  が発生する
などがある

自分でSimpleDateFormatを一切使わなくても、new Date().toString()を
多用すると同じ。(と、思うけど。内部でSimpleDateFormatを使っている)

[関連情報]

NumberFormatなど、他のFormatのサブクラスも、元々スレッドセーフでは
ないんだけど、NumberFormat#format()は直すの簡単だったからスレッド
セーフにしたよ。と、なんだかいいかげんにも見える理由で、
NumberFormat#format()は大丈夫らしい。(NumberFormat#parse()の方は
だめらしい)
http://developer.java.sun.com/developer/bugParade/bugs/4101500.html

[Core APIのスレッドセーフ性について]

Bug Paradeのcommentsでよく不満が述べられていることだが、Javaの
ドキュメントに「そのクラスがスレッドセーフか否か」が書かれていな
いことが一番の問題である。

マルチスレッド環境下で使おうとするクラスを、いちいちソースを読ん
で自分でthread-safenessを確認しなければならないというのは、現実
的とは思えない。さてどうしたものか。

[他のログを取るソフトウェアはどうしているのか]

SimpleDateFormatがスレッドセーフでないことを、世の有名ソフトウェアは
どう回避しているのか、オープンソースのプロダクトを調査した

調査対象は、以下の観点で選択した。
 - Javaのオープンソース製品
 - ログライブラリ、またはログを多用するサーバアプリケーション
 - 多くのユーザがついていること(==ヘビーユーザがいて、実運用で負荷
   テストが行われている)

●log4j  http://www.log4j.org/

 java.text.SimpleDateFormat より柔軟性はないが、速度を重視した
 4つのDateFormatクラスを独自に作成し、それを使ってログを出して
 いる  (http://www.log4j.org/log4j/HISTORY Jan 29, 2000より)

 ★ここ、バグ問題は別として参考にすべき

 結果として、SimpleDateFormatを使っていないので、問題は起こらない
 ということか。

 開発者用MLのアーカイブも検索したが、DateFormatとスレッドに絡む
 話は出ていないようだ
 http://www.geocrawler.com/lists/3/SourceForge/2715/0/

●Jigsaw  http://www.w3.org/Jigsaw/

 リリースノートの過去のバグには、DateとThreadに関する項目はない
   http://www.w3.org/Jigsaw/RelNotes.html

 MLのアーカイブを検索したが、それらしいものはない
   http://lists.w3.org/Archives/Public/www-jigsaw/

●Tomcat   http://jakarta.apache.org/tomcat/index.html

 バグ追跡システムには、DateとThreadに関する情報なし
   http://znutar.cortexity.com/BugRatViewer/SearchReports

 ★開発者アーカイブ中に、「SimpleDateFormatは有害?」というスレッド
 発見
   http://w6.metronet.com/~wjm/tomcat/2000/Oct/msg00302.html
   http://w6.metronet.com/~wjm/tomcat/2000/Oct/msg00350.html
   http://w6.metronet.com/~wjm/tomcat/2000/Oct/msg00362.html
 ただし、スレッドアンセーフに関する話ではなく、ストレステスト時の
 パフォーマンスを問題にして、改善のためのより高速なDateFormatを提案
 しているもののようだ。(log4jと同様)

 もし、これらで提案/利用されている独自のDateFormatクラスが、
 - SimpleDateFormatの10倍早いという話が本当で、
 - ログで出す日付は、Locale.US形式の日付しかない
 なら、こういったものを利用する/参考にするのがよいかも。

# log4jやtomcatで使っているDateFormatクラスが、ロケールセンシティブ
# かどうかは調べていない。