- - PR -
java.util.TimerTask が state を持つことをどうやって分かるのか?
1
投票結果総投票数:8 | |||
---|---|---|---|
ソースコードを見ろ | 7票 | 87.50% | |
javadocが不完全なのだ | 1票 | 12.50% | |
API は使ってみないことには分からないものなのだ | 0票 | 0.00% | |
|
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-03-21 21:12
TimerTask と Timer の仕様、
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/TimerTask.html http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/Timer.html を見て、たとえば、つぎのようなコーディングをしましたとします。 目論見は main の実行開始時刻(T)の1秒後(T+1秒)に Hello を、2秒後(T+2秒)にも Hello を表示するためです。
しかし、2回目の schedule の呼び出しで IllegalStateException が発生してしまいます。 上記の javadoc を見ても、この理由が分かりません。TimerTask 内部のソースコードを見ると、
という state を持っていることから、なんとなく理由が分かります。 結局はソースコードを見ない限り、API を使用するために必要な仕様は分からないということなのでしょうか?それとも私のアプローチのしかたが正しくなかったのでしょうか? -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} | ||||||||||||
|
投稿日時: 2007-03-21 21:42
一応、Timer#schedule(TimerTask, long)の例外欄に
「タスクがすでにスケジュールされたか取り消された場合」 とあるので、同じタスクを複数回スケジュールできない 仕様であることを推測できなくもないですね。 あとは、TimerTask側にcancel()メソッドを持っていますが、 スケジュールを複数回行えたとすると、いつスケジュールした ものなのか特定できなくなるため、仕様的に破綻してしまいます。 表現的にも意味的にもわかりやすいかは別にして、 繰り返し実行をサポートするための仕様なのでしょう。 | ||||||||||||
|
投稿日時: 2007-03-21 23:38
stateを持つかどうかは別にして
Timer#purge からTimer:TimerTaskが1:nであることは解り Timer#schedule のIllegalStateExceptionの説明の「すでに」の部分から推測できそうな気もしますが 解り難いといえば、そうかもしれないですね。 | ||||||||||||
|
投稿日時: 2007-03-21 23:51
英語版のAPIドキュメントを読むと自明だったりします。
「A task」と「a Timer」ですから、1対1であることが明白です。 | ||||||||||||
|
投稿日時: 2007-03-22 10:30
余談ですが、j2se5以降は java.util.Timer よりも
java.util.concurrent.ScheduledExecutorService を使うほうが推奨されます。 ScheduledExecutorServiceの場合は、RunnableまたはCallableを登録して、ScheduledFutureを受け取り、ScheduledFutureに対してキャンセルを行うので、RunnableやCallableは繰り返し登録することができます。 | ||||||||||||
|
投稿日時: 2007-03-24 17:20
なるほど。英語の原文から欠落している情報がないかにも注意して、文章を深く読む必要がある、ということですね。 なお、今回の質問に至ったのは、TimerTask クラスの state というフィールドが隠蔽されてしまっている(パッケージアクセスになっている)が、それにアクセスするメソッドも隠蔽されてしまっている、というのが解読を困難にしている元だと思ったからです。Timer と TimerTask の間では state を隠蔽していないのに、Timer と TimerTask の外側からは state が見えないようになっている、という作りは、なんだか違和感を感じます。 要は、パッケージアクセスだから見せない、というのが良い作りなのか、というのが疑問なのです。もっとも、Java API のソースコードを見ると、いたるところにパッケージアクセスのフィールドがあります。 TimerTask クラスに戻りますが、この cancel メソッドの実装を見ると、メソッドの戻り値は state フィールドに依存しています。だったら、state フィールドの getter を public で持っていても良いのではないでしょうか。state のすべての状態をあらわにせずとも、
のようなメソッドは持っているべきでは、と思います。
このクラスの存在を知りませんでした。 こっちのほうがシンプルで良さそうですね。 -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} |
1