• ベストアンサー

javaのプログラムが止まる

JAVAを使って、ホームページを読み込んでいるのですが、100000ページくらいのURLを読み込んだ辺りでよく止まってしまいます。なぜでしょうか? また、JAVAがURLを読み込んでいる時に、メールチェックをしたり、たくさんのホームページをIEで見ていても止まることが良くあります。 こういったエラー表示の出ないエラーを解決するにはどうしたらよいでしょうか?とても困っています。 教えていただけないでしょうか? 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.26

えーっと、諦めるのが早くないですか? それに、いろいろヒントや解説も書いてありますし、 どこがわからないのかが逆にわかりません。 それと、「時間がないので作って欲しい」という内容に読みとれますが、 丸投げやそれに類似のリクエストには、申し訳ありませんが応えられません。 これは、私の方針というか、気持ちの問題です。 前回、「こちらで追加してもいいのですが」と書いたため、こういう要望になったのだと 思いますが、言い回しの間違いです。 「こちらで追加できなくはないのですが」ということを言いたかったのでした。 すみません。 というわけですので、直接のコードは書きません。 その代り、質問等はわかる範囲でならいくらでもつきあいます。

mizuki_ff
質問者

お礼

長らく、回答いただき本当に、ありがとうございました。今、コードを勉強する時間がどうしても取れないため、また、時間が取れる時がありましたら新しく質問させていただきますので、その際は、ぜひ、お付き合いよろしくお願いいたします。

その他の回答 (25)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.15

あいかわらず、私の環境では発生しません。 ●java.net.BindException: Address already in use: connectの件  スレッド(というよりソケット)が多すぎるのだと思います。 ドキュメントを見ると、 「ローカルなアドレスおよびポートに対してソケットのバインドを試行中に エラーが発生したことを通知します。  一般的には、ポートが使用中であるか、要求したローカルアドレス割り当てが できないことが原因です。 」 ---JavaAPIより--- 詳しくはわかりませんが、ルータを使っているということなので、その辺りで 出てるのではないかと。。。(^^; いずれにしても、スレッドやソケットを50個も使うのは多すぎますね。 (非常識な行為と言われますよ) ●動作停止の件  #13の補足ですが、コードをいじってません? 「30休憩」のメッセージの出かたがおかしいのですけど。

mizuki_ff
質問者

お礼

お返事いただき、ありがとうございます。 返信です。 >つまり、接続先のサーバーから応答がない。 >しかも、向こうがタイムアウトでの切断をして >くれないのでは、という気がします。 >もしそうだとすると、読み込みにタイムアウトの設定は出来ないので、仕掛けを作る必要がありますね。 もしかすると、ADSLのため、通信回線の不安定さが原因かもしれません。 また、ソケットが重複するとのことですが、このJAVAプログラムを動かしているにOutlookExpress(以下、OE)を使うと Address already in use: connect がでたり、 プログラムが止まったり して、普通にOEが使えず困っています。また、これから先、このソフトをADSLよりも不安定な、AirH”で使う可能性もあるため、 通信が不安定な環境でもタフに動いてくれるプログラムを作りたいと思っています。 どのようなコードになりますか。もしよろしければ、記述していただけないでしょうか? >詳しくはわかりませんが、ルータを使っているということなので、その辺りで >出てるのではないかと。。。(^^; ルーター内臓のADSLモデムを、ハブで分けているので原因かと思ってとりあえず、直接ルーターに つないで見たいのですが、相変わらず先と同じエラーがでます。 >いずれにしても、スレッドやソケットを50個も使うのは多すぎますね。 >(非常識な行為と言われますよ) どのくらいの数が適切なのでしょうか? また、これに対するまずさはどの辺りでしょうか? 以前、質問したときも、この件に関してはかなり指摘がありました。 一番いいのは、スレッド、ソケット数どちらにしても、マシーンや回線速度にマッチした最適が出せればいいのですが・・・ >●動作停止の件 > #13の補足ですが、コードをいじってません? >「30休憩」のメッセージの出かたがおかしいのですけど。 コードは、指摘されたところ意外、特にいじっていませんが、 念のため補足に記述しておきます。

mizuki_ff
質問者

補足

import java.net.*; import java.io.*; class Test { public static void main(String args[]) throws IOException{ try { InputStream is = new FileInputStream("URL.dat"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String h; int lineCnt = 0; for(;;) { h = br.readLine(); if(h == null) {break;} lineCnt ++; } br.close(); is.close(); InputStream is2 = new FileInputStream("URL.dat"); BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); String h2[] = new String[lineCnt]; for(int h2Cnt=0; h2Cnt<lineCnt; h2Cnt++) { h2[h2Cnt] = br2.readLine(); } br2.close(); is2.close(); int setLoop = 10; int loop = 0; int count = 0; Kaiseki2 run[] = new Kaiseki2[lineCnt]; for(int cnt=0; cnt<lineCnt; cnt++) { System.out.println(h2[cnt]); run[cnt] = new Kaiseki2(h2[cnt],cnt); run[cnt].start(); loop++; if(loop == setLoop){ count = loop + count; int loopJoin = 0; loopJoin = cnt + 1 - setLoop; for(int i=1; i<=setLoop; i++){ run[loopJoin].join(); loopJoin++; loop=0; } System.out.println("Test() "+": "+count); System.out.println("30休憩"); Thread.sleep(30000);//30休憩 } } int reJoin = lineCnt%setLoop; int reloop = lineCnt - reJoin; for(int i=1; i<=reJoin; i++){ run[reloop].join(); reloop++; } System.out.println("Test(Finish) "+": "+reloop); if(reloop == lineCnt){System.out.println("O.K.");}else{System.out.println("Err");} }catch(Exception ex){ System.out.println("エラー:Test()"); System.out.println(ex.getMessage()); } } } class Kaiseki2 extends Thread { private String h = null; private int id; Kaiseki2(String str,int id) { this.h = str; this.id = id; } public void run() { System.out.println(id + " start"); int LOOP_MAX = 10; int loopcnt = 0; try { OutputStream os = new FileOutputStream("出力.txt",true); BufferedWriter fr = new BufferedWriter(new OutputStreamWriter(os)); URL url = new URL(h); while(loopcnt < LOOP_MAX){ try{ System.out.println(id + " ストリーム取得開始"); InputStream is = url.openStream(); System.out.println(id + " ストリーム取得終了"); BufferedReader in = new BufferedReader(new InputStreamReader(is,"JISAutoDetect")); for (;;) { String i = in.readLine(); if( i == null) {break;} if(i.indexOf("http")!=-1){ fr.write(i.indexOf("http")+"\n"); } } in.close(); break; }catch(Exception e){ loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("20秒休憩"); // ウェイト処理 e.printStackTrace(); System.out.println(e.getMessage()); Thread.sleep(20000); } } fr.close();System.out.println("30休憩"); os.close();//外に出すこと }catch(Exception ex){System.out.println("エラー:Kaiseki2()");System.out.println(ex.getMessage());} System.out.println(id + " end"); } }

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.14

すみません。さらにもう1つ。 BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); を System.out.println(id + " ストリーム取得開始"); InputStream is = url.openStream(); System.out.println(id + " ストリーム取得終了"); BufferedReader in = new BufferedReader(new InputStreamReader(is,"JISAutoDetect")); としてみて下さい。

mizuki_ff
質問者

お礼

追伸 このエラーは、 Test の int setLoop = 10;→int setLoop = 50; にして実験しています。 また、このエラーが起こる前には、インターネット(インターネットエクスプローラー)でたくさんのページを観覧したり、このJAVAプログラムを立ち上げて、閉じた後でした。

mizuki_ff
質問者

補足

もうひとつ、エラーのほうが発生いたしましたので、記載いたします。 宜しくお願い致します。 ---------------------------------- 37 start 38 start 39 start http://www.itar-tass.com/ http://www.afp.com/ http://www.unian.net/ http://www.spa.gov.sa/ http://www.nampa.org/ http://www.iha.com.tr/bin/directory.dll/pf 22 ストリーム取得開始 21 ストリーム取得開始 40 start 41 start 42 start 43 start 44 start 45 start http://www.anp.nl/ http://www.tvguide.or.jp/cgi-bin/top.cgi http://www.aniin.com/ 24 ストリーム取得開始 23 ストリーム取得開始 46 start 47 start 48 start 49 start 4 ストリーム取得開始 26 ストリーム取得開始 25 ストリーム取得開始 5 ストリーム取得開始 9 ストリーム取得開始 27 ストリーム取得開始 12 ストリーム取得開始 13 ストリーム取得開始 14 ストリーム取得開始 28 ストリーム取得開始 29 ストリーム取得開始 31 ストリーム取得開始 30 ストリーム取得開始 33 ストリーム取得開始 32 ストリーム取得開始 8 ストリーム取得開始 7 ストリーム取得開始 35 ストリーム取得開始 34 ストリーム取得開始 11 ストリーム取得開始 15 ストリーム取得開始 10 ストリーム取得開始 36 ストリーム取得開始 16 ストリーム取得開始 6 ストリーム取得開始 39 ストリーム取得開始 38 ストリーム取得開始 41 ストリーム取得開始 40 ストリーム取得開始 43 ストリーム取得開始 42 ストリーム取得開始 47 ストリーム取得開始 44 ストリーム取得開始 45 ストリーム取得開始 37 ストリーム取得開始 49 ストリーム取得開始 48 ストリーム取得開始 46 ストリーム取得開始 http://jahon.mfa.uz/english.html 1 20秒休憩 http://www.aniin.com/ 1 20秒休憩 http://www.itar-tass.com/ 1 20秒休憩 http://www.paknews.com/ 1 20秒休憩 http://www.habena.ba/ 1 20秒休憩 http://www.yonhapnews.co.kr/ 1 20秒休憩 48 ストリーム取得終了 http://www.europapress.es/ 1 20秒休憩 http://www.jamahiriyanews.com/ 1 20秒休憩 27 ストリーム取得終了 30休憩 48 end java.net.BindException: Address already in use: connect30休憩 27 end 14 ストリーム取得終了 33 ストリーム取得終了 47 ストリーム取得終了 at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(Unknown Source) at java.net.PlainSocketImpl.connectToAddress(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source)38 ストリーム取得終了 24 ストリーム取得終了 12 ストリーム取得終了 17 ストリーム取得終了 36 ストリーム取得終了 16 ストリーム取得終了 Address already in use: connect 4 ストリーム取得終了 30休憩 38 end 30休憩 16 end 30休憩 36 end 30休憩 4 end 30休憩

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.13

すみませN、もう1箇所。 Kaiseki2のループ中の例外キャッチで、1行追加して下さい。 loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("20秒休憩"); // ウェイト処理 System.out.println(e.getMessage()); e.printStackTrace(); //<---追加 Thread.sleep(20000);

mizuki_ff
質問者

補足

もうひとつエラーが発生しました。 これが表示された状態で全く先に進みません。もうすでに、15分間、動いていません。 あと、このプログラムを動作させている時, 時々、インターネットに一切つながらなくなるというエラーが起きます。もしかすると、これも関係ありますかね? 因みに、同一のルーターから分配されているパソコンでは問題なくホームページが見れます。また、この繋がらないという状態が復旧した後も、プログラムは停止したままです。 宜しくお願い致します。 ------------------------------------- http://www.pakistan-news.com/ 67 start 67 ストリーム取得開始 68 start 68 ストリーム取得開始 63 start 63 ストリーム取得開始 69 start 69 ストリーム取得開始 60 ストリーム取得終了 30休憩 60 end 66 ストリーム取得終了 30休憩 66 end 61 ストリーム取得終了 30休憩 61 end 63 ストリーム取得終了 62 ストリーム取得終了 68 ストリーム取得終了 30休憩 68 end 67 ストリーム取得終了 64 ストリーム取得終了 30休憩 64 end 30休憩 63 end 30休憩 67 end 65 ストリーム取得終了 30休憩 65 end 69 ストリーム取得終了 30休憩 69 end 30休憩 62 end Test() : 70 30休憩 http://www.ips.org/ http://www.tanjug.co.yu/ http://www.jiji.com/ http://www.site.kz/news.php http://www.bns.ee/ http://www.cananews.com/ 70 start 70 ストリーム取得開始 71 start 71 ストリーム取得開始 72 start 72 ストリーム取得開始 73 start 73 ストリーム取得開始 74 start 74 ストリーム取得開始 http://www.noyan-tapan.am/ http://www.ndn-news.co.jp/ http://www.armenpress.am/ http://www.kyodo.co.jp/ 75 start 75 ストリーム取得開始 76 start 76 ストリーム取得開始 77 start 77 ストリーム取得開始 78 start 78 ストリーム取得開始 79 start 79 ストリーム取得開始 72 ストリーム取得終了 30休憩 72 end 77 ストリーム取得終了 79 ストリーム取得終了 30休憩 77 end 30休憩 79 end 75 ストリーム取得終了 30休憩 75 end 73 ストリーム取得終了 70 ストリーム取得終了 71 ストリーム取得終了 30休憩 71 end 30休憩 70 end 30休憩 73 end 78 ストリーム取得終了 30休憩 78 end 74 ストリーム取得終了 30休憩 74 end 76 ストリーム取得終了 -------------------------------------

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.12

困りました。ソースを動かしましたがなかなか現象が発生しません。 とりあえず、そちらでも次のことをしてみて下さい。 まずは、どこで動かなくなっているのかを特定しましょう。 スレッドの開始と終了時にメッセージを出します。 ただ出したのでは、どのスレッドかわからないので、 Kaiseki2を class Kaiseki2 extends Thread {  private String h = null;  private int id;  Kaiseki2(String str, int id) {   this.h = str;   this.id = id;  } とします。 あとは、runメソッドの開始に System.out.println(id + " start"); 終了に、 System.out.println(id + " end"); とします。 Testクラスでは、 for(int cnt=0; cnt<lineCnt; cnt++) {  System.out.println(h2[cnt]);       //<----コメントを外す  run[cnt] = new Kaiseki2(h2[cnt], cnt); // <----変更  run[cnt].start(); と直します。 こうして、どこで止まっているのかを限定して下さい。 ●本の件  例はC++で書いてありますが、メインはコードではなく考え方ですし、 書いてあるコードも難しいものではないので、問題はないと思います。

mizuki_ff
質問者

お礼

■本の件 なるほど!了解しました。 とりあえず、オンラインショップで購入してみます。 因みに、今は、ソフトをGUIで使いたいので やさしいJAVA活用編を読解中です。 エラーについては記述容量に限りがあるので、補足やお礼にて書いていきますので、宜しくお願い致します。 ■プログラムの件 今確認できたエラーは2つ ■1つは、URLがもとより読めないケース 表示された画面は下記の通り ■それでも、何度か、プログラムを立ち上げては閉じ、 を繰り返していると、作動する。 動作したときに起こったエラーは最下段の通り、 しかし、3度目のトライで無事読めたため次に移った模様。 そのため、今は、正常に次のURLを読んでいる模様。 ---------------------------------------------- http://jahon.mfa.uz/english.html http://www.ceskenoviny.cz/news/ http://www.sapa.org.za/ 0 start 0 ストリーム取得開始 1 start 1 ストリーム取得開始 http://www.aman-alliance.org/ http://www.nni-news.com/ 3 start 2 start http://www.aib.bf/ http://www.presseamt.li/ http://www.wafa.pna.net/ http://www.yonhapnews.co.kr/ http://www.telam.com.ar/ 4 start 5 start 6 start 7 start 8 start 9 start ----------------------------------------------

mizuki_ff
質問者

補足

---------------------------------------------- 22 ストリーム取得終了 30休憩 22 end Test() : 30 30休憩 http://www.cp.org/ http://www.montsame.mn/ 30 start 30 ストリーム取得開始 http://www.mti.hu/ http://www.interfax-news.com/ http://www.lusa.pt/ http://www.zana.gov.zm/ http://www.bulls.no/ http://www.upi.com/ 31 start 31 ストリーム取得開始 32 start 32 ストリーム取得開始 33 start 33 ストリーム取得開始 34 start 34 ストリーム取得開始 35 start 35 ストリーム取得開始 36 start 36 ストリーム取得開始 http://www.adi.dj/ http://www.anadoluajansi.com.tr/ 37 start 37 ストリーム取得開始 38 start 38 ストリーム取得開始 39 start 39 ストリーム取得開始 37 ストリーム取得終了 30休憩 37 end 30 ストリーム取得終了 30休憩 30 end 33 ストリーム取得終了 30休憩 33 end 36 ストリーム取得終了 30休憩 36 end 32 ストリーム取得終了 38 ストリーム取得終了 30休憩 38 end 34 ストリーム取得終了 35 ストリーム取得終了 30休憩 32 end 30休憩 34 end 30休憩 35 end 31 ストリーム取得終了 30休憩 31 end http://www.anadoluajansi.com.tr/ 1 20秒休憩 java.net.UnknownHostException: www.anadoluajansi.com.trwww.anadoluajansi.com.tr at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at java.net.URL.openStream(Unknown Source) at Kaiseki2.run(Test.java:99) 39 ストリーム取得開始 http://www.anadoluajansi.com.tr/ 2 20秒休憩 java.net.UnknownHostException: www.anadoluajansi.com.trwww.anadoluajansi.com.tr at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at java.net.URL.openStream(Unknown Source) at Kaiseki2.run(Test.java:99) 39 ストリーム取得開始 39 ストリーム取得終了 30休憩 39 end Test() : 40 30休憩 ----------------------------------------------

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.11

えーっと、「とりあえず動くようにしたい」ということだと理解しましたけど、いいでしょうか? でしたら、 1.エラーメッセージの正確な内容。 2.その時のソース(#9から何も変えていなければそれで結構です)。 3.URL.DATの件数 は必須ですので、それを提示して下さい。 オブジェクト指向の件は、勉強しておいた方がいいと思いますよ。 きれいなプログラムを作れるようになるかもしれません。 きれいなプログラムは、バグが出にくく、デバッグもしやすく、拡張もしやすいという傾向がありますから。。。

mizuki_ff
質問者

お礼

文字数の関係で#10、11のお礼欄も質問に使わせていただきます。あらかじめ、ご了承下さい。 ■オブジェクト指向の件と本について 長所がたくさんあるようなので、是非、勉強したいですね。しかし、書籍紹介についてですが、C++がベースになっているのはどうかと。できれば、JAVAに直接関係ある書籍のほうが嬉しいのですが・・・それとも、この本でも、きれいなソースやオブジェクト指向をを書くという意味では、どちらでもあまり関係ないですかね?どうでしょうか? ■動くプログラムにしたい件について えーっと、「とりあえず動くようにしたい」ということだと理解しましたけど、いいでしょうか? はい!よろしくお願いいたします!! もう、私にはお手上げ状態だったのでとてもありがたいです!!!! 以下、情報です。分からないことがあったらなんでも聞いてください。 1.エラーメッセージの正確な内容。 >>当、書き込み 2.その時のソース(#9から何も変えていなければそれで結構です)。 >>補足参照 3.URL.DATの件数 >>#10お礼欄参照 1.エラーメッセージが表示されない状態でプログラムが先に進まない。 1時間たっても先に進みません・・・ また、エラーの表示画面がなぜかされないので、画面に、表示されたものを書いておきます。 再現性については、あったりなかったりと、これという理由が思い当たりません。 もしかすると、WindowsXpが不安定??しかし、JAVAを動かす前に、 再起動してその後は、マウスすら触らなくても同様のことが起こることもある。 起こらず、Test() : 60も正常に表示されることもある。 しかし、続けていると、いつの間にかエラー表示がない状態で止まる。 ---------------- Test() : 20 30休憩 Test() : 40 30休憩 ----------------

mizuki_ff
質問者

補足

2.ソース Test.java ----------------------------- import java.net.*; import java.io.*; class Test { public static void main(String args[]) throws IOException{ try { InputStream is = new FileInputStream("URL.dat"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String h; int lineCnt = 0; for(;;) { h = br.readLine(); if(h == null) {break;} lineCnt ++; } br.close(); is.close(); InputStream is2 = new FileInputStream("URL.dat"); BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); String h2[] = new String[lineCnt]; for(int h2Cnt=0; h2Cnt<lineCnt; h2Cnt++) { h2[h2Cnt] = br2.readLine(); } br2.close(); is2.close(); int setLoop = 10; int loop = 0; int count = 0; Kaiseki2 run[] = new Kaiseki2[lineCnt]; for(int cnt=0; cnt<lineCnt; cnt++) { // System.out.println(h2[cnt]); run[cnt] = new Kaiseki2(h2[cnt]); run[cnt].start(); loop++; if(loop == setLoop){ count = loop + count; int loopJoin = 0; loopJoin = cnt + 1 - setLoop; for(int i=1; i<=setLoop; i++){ run[loopJoin].join(); loopJoin++; loop=0; } System.out.println("Test() "+": "+count); System.out.println("30休憩"); Thread.sleep(30000);//30休憩 } } int reJoin = lineCnt%setLoop; int reloop = lineCnt - reJoin; for(int i=1; i<=reJoin; i++){ run[reloop].join(); reloop++; } System.out.println("Test(Finish) "+": "+reloop); if(reloop == lineCnt){System.out.println("O.K.");}else{System.out.println("Err");} }catch(Exception ex){ System.out.println("エラー:Test()"); System.out.println(ex.getMessage()); } } } class Kaiseki2 extends Thread { private String h = null; Kaiseki2(String str) { this.h = str; } public void run() { int LOOP_MAX = 10; int loopcnt = 0; try { OutputStream os = new FileOutputStream("出力.txt",true); BufferedWriter fr = new BufferedWriter(new OutputStreamWriter(os)); URL url = new URL(h); while(loopcnt < LOOP_MAX){ try{ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); for (;;) { String i = in.readLine(); if( i == null) {break;} if(i.indexOf("http")!=-1){ fr.write(i.indexOf("http")+"\n"); } } in.close(); break; }catch(Exception e){ loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("20秒休憩"); // ウェイト処理 System.out.println(e.getMessage()); Thread.sleep(20000); } } fr.close(); os.close();//外に出すこと }catch(Exception ex){System.out.println("エラー:Kaiseki2()");System.out.println(ex.getMessage());} } } -----------------------------

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.10

●動作保証がない件  あのソースでは、各スレッドが同一のファイルをオープン・書き込みを しています。これはいいですよね?  つまり、スレッドAがファイルをオープン・書き込みしている最中に、 スレッドBが同じファイルに対し、オープン・書き込みをしようとするわけです。  このときの動作はOS等に依存すると思います。  つまり、あのプログラムは動作保証がないということになります。 ●オブジェクトをスレッドに渡す件  例えば、InputStreamなどのオブジェクトを各スレッドに渡すということです。 ただし、InputStreamそのものは同期化対応されてないので、これを同期化させた オブジェクトに改造する必要があります。  同期化されていないと、スレッドAが「ABCDE」、スレッドBが「123456」 という書き込みが同時に実行された場合、ファイルには「A1BC234D5E6」などのように なる可能性があるからです。 ●勉強方法・教科書等の件  ちょっと言い方が悪いかもしれませんが、もともにというか、まじめにというか、 正しい学習方法は、JAVA言語からではなく、オブジェクト指向の概念を 学ぶことから始めることです。  JAVA言語というのはオブジェクト指向の概念を具体化するためのものなのです。  「クラス」、「継承」、「汎化」などはオブジェクト指向の用語です。 この概念を知らないでJAVA言語を使うのは、英語を覚えた普通の日本人が、 アメリカ人の大学教授と、彼の専門分野に関して会話をするのと同じ事です。 言葉そのものは話せても、会話にはならないでしょう。  その意味から、オブジェクト指向の概念を学ぶのが本道です。  ただ、このような、概念を理解するのは難しいので、本を1冊読んだだけで済むとは 思わないでください。数冊読んでなんとなくわかるものです。  今は、書籍も多く出ているので、「オブジェクト指向」をキーワードで探せば直ぐに見つかると 思います。簡単そうなのを選んで下さい。  私が好きなのは、「憂鬱なプログラマのためのオブジェクト指向開発講座」という本です。 これを読んで、目から鱗が落ちました。  難点を言えば例がC++で記述されていること、表記方法が現在主流のUMLではないことです。 しかし、オブジェクト指向の概念を学ぶのには良い本だと思います。 http://www.amazon.co.jp/exec/obidos/ASIN/4881356194/249-3343961-0453914 ●質問  前回の質問では、Webページを監視し続けるプログラムを作りたいとのことでしたが、 今回のプログラムでは、リストアップされたページをダウンロードして終わりのようです。 方向転換したのですか? ●その他  全体構造を見直すつもりがあるのなら、手伝いますけどどうします?  ただし、少し時間はかかるかもしれませんけど(会話に)。

mizuki_ff
質問者

お礼

URL.dat (こんな感じのものが140件つづきます。140件以降は、もう一度始めに戻って繰り返しです。プログラム制御ではなく、実際のURL.datはコピーの繰り返しで代用しています。 例: URL1 URL2 ・・・ ・・・ URL139 URL140 URL1 URL2 ・・・ ・・・ URL140 ) ---------------- http://jahon.mfa.uz/english.html http://www.ceskenoviny.cz/news/ http://www.sapa.org.za/ http://www.aman-alliance.org/ http://www.nni-news.com/ http://www.aib.bf/ http://www.presseamt.li/ http://www.wafa.pna.net/ http://www.yonhapnews.co.kr/ http://www.telam.com.ar/ http://www.jamahiriyanews.com/ http://www.np-net.co.jp/ http://www.ansa.it/ http://www.noticiasargentinas.com/ http://www.omannews.com/ http://www.kplnet.net/ http://www.inforpressca.com/inforpress/ http://www.irna.com/en/ http://www.adn.de/ http://www.dinau.com/ http://www.sofiapress.bg/index_en.htm http://www.fides.org/ http://www.habena.ba/ http://www.paknews.com/ http://www.reuters.com/ http://www.aps.dz/ http://www.srna.co.yu/ http://china.kyodo.co.jp/ http://www.ana.gr/ http://www.agenceurope.com/ http://www.cp.org/ http://www.montsame.mn/ http://www.mti.hu/ http://www.interfax-news.com/ http://www.lusa.pt/ http://www.zana.gov.zm/ http://www.bulls.no/ http://www.upi.com/ http://www.adi.dj/ http://www.anadoluajansi.com.tr/ http://www.europapress.es/ http://www.itar-tass.com/ http://www.afp.com/ http://www.unian.net/ http://www.spa.gov.sa/ http://www.nampa.org/ http://www.iha.com.tr/bin/directory.dll/pf http://www.anp.nl/ http://www.tvguide.or.jp/cgi-bin/top.cgi http://www.lena.gov.ls/news.htm http://www.aniin.com/

mizuki_ff
質問者

補足

丁寧な、回答いただき本当にありがとうございます。 動作保証がない件、オブジェクトをスレッドに渡す件、一応理解できました。ありがとうございます。 教科書・勉強の件 オブジェクト指向からですか・・・ 確かに、一度勉強してみてもいい気もしています。逆に、習うより慣れろで、どんどん、コードを書いてある程度使えるようになってから専門書を読む方がより円滑に学習ができるかもという期待もあります。いずれにしても、とりあえずは、本の方を入手してみようと思います。 例え>専門化との会話 会話にならない。確かにそうかもしれませんが、一般的なことでしたらまだ、カバーできるのではないかと思いますがいかがでしょうか。自分がどのくらいのレベルにあるのかが分からないのでなんともいえませんが、少なくとも、今回のプログラム位であれば少しの助言があれば結構簡単にデバッグできるのではないかと思っているのですが、難しいでしょうか?もしよろしければ、このプログラムを正常に動作させるコードを教えていただけないでしょうか? #9の動作、報告です 全ての読み込みに、同期を取ると、気持ちのせいかもしれませんが、どことなく、安定した感(address already in use: connect javaエラーの数が減った気がする)はあるのですが、 ・address already in use: connect java ・Unexcepted end of file from server ・エラー表示せずに止まる 上記3つのエラーが依然でます。 もしよろしければ、このコードを正常に動作させるJAVAプログラムを教えていただけないでしょうか? 宜しくお願い致します。 方向転換したのですか? >とりあえず、このエラーがなくなるまでは前に進めそうにありません。全てを自動化しなくても、取得したデータをExcelに入力するとJAVAでするよりも遥かに手軽にできるため、全自動化はあまり急いでいません。とりあえずは、このコードをまともに動作させることに勤めたいと思っています。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.9

質問とは直接関係がないので書かなかったのですが、 1.配列のインデックスは0から使えます(普通0から使います) 2.mainメソッド内の、   String h[] = new String[cnt];   h[cnt-1] = br.readLine();   は配列にしている意味がありません。   毎回、配列が初期化されています。 3.出力ファイル「出力.txt」は各スレッドで使うため、動作が保証されないと思います。 4.Kaiseki2#run()メソッドのwhileループでは、2回目のループで、閉じられた出力ファイル(fr)に対して書き込みをしようとしています(fr.write(i+"\n");)。 1,2に関しては、まずファイルの内容を全てjava.util.ArrayListに読み込んでしまったらいいと思います。 3は、一時ファイルを使うか、スレッドにidを付けておいて、ファイル名にそのidを付加する ことで、スレッド毎に違う名前になります。 もし、全てのスレッドが同じファイルに書き込みをしたいのなら、ちょっと仕掛けが必要です。 出力ファイルアクセス用のクラスを作って、そのオブジェクトをスレッドに渡します。 スレッドから使用される、ファイル書き込み用のメソッドは同期メソッドにしておく必要があります。 4は何をしたいのかがわからないので、アドバイスできません。

mizuki_ff
質問者

お礼

お礼欄で申し訳ありませんが、回答についての質問です。 >>良く分からない部位<< 出力ファイル「出力.txt」は各スレッドで使うため、動作が保証されないと思います。 もし、全てのスレッドが同じファイルに書き込みをしたいのなら、ちょっと仕掛けが必要です。出力ファイルアクセス用のクラスを作って、そのオブジェクトをスレッドに渡します。スレッドから使用される、ファイル書き込み用のメソッドは同期メソッドにしておく必要があります。 >><< >>動作保証がない点とそのオブジェクトをスレッドに渡すという2点が良く分かりません。 どういう意味でしょうか???

mizuki_ff
質問者

補足

上記のアドバイスを参考にして作り直してみました。 少しばかり、無駄が多いプログラムの気もしますが、まともに動作していますので、最新のコードを記載いたします。 なお、以前と同じエラーが出るか否かについては、今、ADSL回線がまともに使えない場所に居ますので、後ほどレポートさせていただきます。 何か、良いアドバイスがありましたら、宜しくお願い致します。 import java.net.*; import java.io.*; class Test { public static void main(String args[]) throws IOException{ try { InputStream is = new FileInputStream("URL.dat"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String h; int lineCnt = 0; for(;;) { h = br.readLine(); if(h == null) {break;} lineCnt ++; } br.close(); is.close(); InputStream is2 = new FileInputStream("URL.dat"); BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); String h2[] = new String[lineCnt]; for(int h2Cnt=0; h2Cnt<lineCnt; h2Cnt++) { h2[h2Cnt] = br2.readLine(); } br2.close(); is2.close(); int setLoop = 3; int loop = 0; int count = 0; Kaiseki2 run[] = new Kaiseki2[lineCnt]; for(int cnt=0; cnt<lineCnt; cnt++) { run[cnt] = new Kaiseki2(h2[cnt]); run[cnt].start(); loop++; if(loop == setLoop){ count = loop + count; int loopJoin = 0; loopJoin = cnt + 1 - setLoop; for(int i=1; i<=setLoop; i++){ run[loopJoin].join(); loopJoin++; loop=0; } System.out.println("Test() "+": "+count); } } int reJoin = lineCnt%setLoop; int reloop = lineCnt - reJoin; for(int i=1; i<=reJoin; i++){ run[reloop].join(); reloop++; } System.out.println("Test(Finish) "+": "+reloop); }catch(Exception ex){System.out.println("エラー:Test()"); System.out.println(ex.getMessage()); } } } class Kaiseki2 extends Thread { private String h = null; Kaiseki2(String str) { this.h = str; } public void run() { int LOOP_MAX = 10; int loopcnt = 0; try { OutputStream os = new FileOutputStream("出力.txt",true); BufferedWriter fr = new BufferedWriter(new OutputStreamWriter(os)); URL url = new URL(h); while(loopcnt < LOOP_MAX){ try{ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); for (;;) { String i = in.readLine(); if( i == null) {break;} if(i.indexOf("http")!=-1){ fr.write(i.indexOf("http")+"\n"); } } in.close(); break; }catch(Exception e){ loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("30秒休憩"); System.out.println(e.getMessage()); Thread.sleep(30000); } } fr.close(); os.close(); }catch(Exception ex){System.out.println("エラー:Kaiseki2()");System.out.println(ex.getMessage());} } }

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.8

>多分、何時間か作動させればそのうち止まるのではないかと考えています。 なにか、良い案はないでしょうか? プログラムの流れが、うまく制御できていないのだと思いますよ。 想定しているのと違う動きをしていて、エラーが出ているのでしょう。 このプログラムからは、意図が見えにくいので 2.各クラス(Test、Kaiseki2)の役割 3.全体の流れ(概略で結構ですが、説明には各クラスを登場させてください) を教えてください。

mizuki_ff
質問者

補足

再三の書き込みいただき本当にありがとうございます。 多分、コードを見れば、お分かりになっていると思いますが、まだ、言語というものに触って間がない状態です。 しかも、独学の時間をかける割にはかどっていない気がします。 こんなひよこに、回答をきありがとうございます!! ■役割について Testでloopの回数分のURLをURL.datから読み取りだし、スレッドにながしています。そして、loop回数に達すると、最後にKaiseki2に投げたURLの解析を終了するまでjoinを用いて新規のスレッド作成を中断しています。 また、#2にある、Kaiseki2では、実装されているものは、ソースデータより、URLアドレスを抜き出す作業をやっています。煩雑なコードになっているため今回は省略しています。因みに、今回は、Test用に、下記のコードに置き換えていますが、それでも同様のエラーが発生します。 fr.write(i+"\n"); → if(i.indexOf("http")!=-1){fr.write(i.indexOf("http")+"\n");} また、本当なら、 ・・・・・・・・・・ if(loop == 2){ count = cnt - 1; System.out.println("Kaiseki() : " + count); run[cnt-2].join(); run[cnt-1].join(); loop=0; } ・・・・・・・・・・ としたいのですがエラーがでて出来ていません。また、一番良いのは、全てのスレッドが終了したら新しくスレッドを開始したいのですが良いコードを思いつくことが出来ていません。 全体の流れは、とりあえず、これで、テキストを作成して、Javaプログラムをとりあえず終了させて、Excelでの処理(手動)にしていますので流れは以上となります。 回答の内容からは外れますが、今の教科書は「やさしいJava第2版」で、メソッドの使い方やJAVA用語の概念がいまいちの見込めないため、習うよりは慣れろということで、様々なホームページより、使えそうなコードをコピーして、自分の必要な物に改造しています。そして、コンパイルエラーがなく、動けばとりあえずは成功というスタンスでやってきています。しかし、コンパイルエラーがなくても、使っているといろいろトラブルが出てきますね。なんとか、Javaを独学したいのですが、こんな調子で良いのでしょうかね?オススメの教科書や、勉強方法がありましたら、教えていただけると幸いです。

  • uzzra
  • ベストアンサー率43% (55/127)
回答No.7

人によってお勧めの本は色々でしょうが、 私は翔泳社の「独習Java」(黄色い本)を最初に読みました。 ソケットについても触れられています。

参考URL:
http://www.amazon.co.jp/exec/obidos/ASIN/4798102784/249-3646649-7655555
  • uzzra
  • ベストアンサー率43% (55/127)
回答No.6

下記のURLが役に立つかもしれません。 Javaで同様の問題が発生した人の例です。 下記URLの場合、JDBCの接続ですが、HTTPと同じように考えて差し支えないと思います。 ご不明な点がありましたら、またお書きください。

参考URL:
http://www.mysql.gr.jp/mysqlml/mysql/msg/9640
mizuki_ff
質問者

補足

回答いただきありがとうございます。 正直、何が書いてあるのかさっぱりでした。 残念ながら、私には無理かもしれません。 もうすこし、JAVAの勉強をやったほうがいいかとも思っていますが、もし、参考になる本がありましたら、宜しくお願い致します。

関連するQ&A