- PR -

Timerクラスの使い方について

投稿者投稿内容
唐竹
会議室デビュー日: 2005/05/03
投稿数: 14
投稿日時: 2005-06-14 15:33
こんにちわ,唐竹と申します。
Timerの使い方について質問させて下さい。
現在,下記のようなメソッドを作っています。

private boolean check(String sUrl) {
URL url = new URL(sUrl);
url.openStream();
return true;
}

このメソッドで,url.openStream()を行った場合,サーバーによっては
応答が返ってくるのにかなりの時間がかかることがあります。
そこでTimerクラスを用いて,
「30秒応答がかえってこなければfalseを返す」
というようなことをやりたいと考えています。

TimerTask task = new TimerTask() {
public void run() {

}
};
Timer timer = new Timer();
timer.schedule(task, 3000);

以上のようなことをやればいいかなと考えたのですが,
run()の中身をどう記述していいものやら分からなくなり,
手詰まりとなってしまいました。
よろしくお願いいたします。

また,現在作成中のプログラムは自作の検索ロボットです。
javaを用いた検索ロボット作成の参考になるような書籍,
サイト等ありましたら教えていただけるとこれまたありがたいです。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2005-06-14 16:39
唐竹さん、こんにちは。

私なら、URLから InputStreamを取る方法ではなく、
Socketクラスを使います。
コード量は増えますが柔軟性が高く、本課題は
タイムアウト時間の設定で実現できます。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2005-06-14 16:48
いくつか方法はあると思いますが、一案を述べてみます。

独自の例外クラス MyTimeOutException(名前は仮称)を定義し、TimerTask#run() の実装中では、単にこれを throw します。
(特に独自のクラスとする必要性はありませんが、スタックトレースを見て他の例外と明確に区別できるよう、ここでは独自にしてあります。)

check(String) メソッド中では、URL オブジェクトを作った次あたりでTimer#schedule(TimerTask, long) メソッドを実行し、url.openStream() 自体は try 節の中で実行します。

url.openStream() が時間内に返ってくれば try 節の中で return true、タイムアウトして catch(MyTimeOutException) 節に処理が移れば return false。
これで比較的わかりやすく書けると思いますがいかがでしょうか。

url.openStream() が成功した場合にこれを close していないのが気になりましたが、これも初期値 null の InputStream 型変数で受けておき、finally 節でチェックして close するというスタンダードな方法で書けます。
いっきゅう
大ベテラン
会議室デビュー日: 2004/04/04
投稿数: 153
お住まい・勤務地: 兵庫
投稿日時: 2005-06-14 17:11
私もTimerを使う必要は感じないですが
わざわざSocketを使う必要もないと思います。

URLからコネクションを取得する方法でも
以下のサイトを参考に様々なプロパティ設定が可能です。
http://java.sun.com/j2se/1.4/ja/docs/ja/guide/net/properties.html
sun.net.client.defaultConnectTimeout
sun.net.client.defaultReadTimeout
(Tigerならメソッドも用意されていたような..)

おせっかいになるかも知れませんが
作られているのが検索ロボットということですからTimerよりも
Threadで一度に複数処理を考えた方がいいと思います。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2005-06-14 17:41
引用:

いっきゅうさんの書き込み (2005-06-14 17:11) より:
(Tigerならメソッドも用意されていたような..)



URLConnection#setConnectTimeout()、setReadTimeout() がありますね。
唐竹
会議室デビュー日: 2005/05/03
投稿数: 14
投稿日時: 2005-06-14 19:18
引用:

Kissingerさんの書き込み (2005-06-14 16:39) より:
私なら、URLから InputStreamを取る方法ではなく、
Socketクラスを使います。



ご返信ありがとうございます。
ソケットについての知識はいまのところ全くありません。
ですが,かじらなければと思っていたところなのでこれから本屋に行って
それ系の本をちょっと立ち読みしてみようと思います。
ネットでちょっと調べた限りは,サーバプログラムとクライアントプログラム間の
通信についてが主で,私が使いたい部分の端的な例は見つかりませんでした。

恰好のサイトがありましたらお教え下さい。
唐竹
会議室デビュー日: 2005/05/03
投稿数: 14
投稿日時: 2005-06-14 19:23
引用:

Gioさんの書き込み (2005-06-14 16:48) より:
独自の例外クラス MyTimeOutException(名前は仮称)を定義し、TimerTask#run() の実装中では、単にこれを throw します。

・・・

url.openStream() が成功した場合にこれを close していないのが気になりましたが、これも初期値 null の InputStream 型変数で受けておき、finally 節でチェックして close するというスタンダードな方法で書けます。



ご返信ありがとうございます。
TimerTask#run()が明示的に例外をthrowするようにしてみたのですが,eclipseに怒られてしまいました。
もしかして,TimerTask#run()は明示的に例外をスローできない??
TimerTask#run() throws MyTimeOutExceptionは,
問題のある記述でしょうか?

ストリームをクローズしていないとのご指摘ありがとうございます。
うっかり忘れていました。finallyでばっちり閉じておきました。
唐竹
会議室デビュー日: 2005/05/03
投稿数: 14
投稿日時: 2005-06-14 19:34
引用:

URLからコネクションを取得する方法でも
以下のサイトを参考に様々なプロパティ設定が可能です。

おせっかいになるかも知れませんが
作られているのが検索ロボットということですからTimerよりも
Threadで一度に複数処理を考えた方がいいと思います。



いっきゅうさん,ご返信ありがとうございます。
サイトを参考にプロパティ設定をしようと試みたのですが,
いかんせん,いまのわたしの能力では理解できませんでした。
もしよろしければ,簡単なソースコードを教えて頂けると嬉しいです。

それから,Threadを使った処理についてのご指摘ありがとうございます。
サーバに接続する部分についてはThreadを使って多重化しています。
タイムアウト処理の部分だけがとても時間を食うので,三日ほど前に
マルチスレッドに切り替えました。まだまだ勉強中です。

>びしばしさん
Tigerですね。。まださわったことがありません。
基本的なことが理解できるようになってから,チャレンジしてみたいと思います。
ありがとうございます。

スキルアップ/キャリアアップ(JOB@IT)