- PR -

URLConnection#getInputStreamで処理が止まる

1
投稿者投稿内容
なつるぎ
会議室デビュー日: 2009/02/20
投稿数: 2
投稿日時: 2009-02-20 16:17
みなさん、こんにちは。

JAVAアプリケーションを開発しているのですが、件名の問題が起きてしまいました。
自力でなんとかしようとしたものの、なかなか糸口が見つからないため、みなさんの知恵をお貸し頂ければと思います。

開発環境は、WinXP(Pro32)、JDK 6 Update 12、Eclipse 3.4.1。
問題のコードは以下の通りです(例外処理は除いています)。
コード:
public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                URL url = new URL("http://www.sample.com/");
                System.out.println("before openConnection");
                URLConnection connection = url.openConnection();
                System.out.println("after openConnection");
                System.out.println("before getInputStream");
                InputStream stream = stream = connection.getInputStream();
                System.out.println("after getInputStream");
                stream.close();
                System.out.println("thread finished");
            };
        };
        thread.start();	// thread.run()とすれば動く
        Scanner scanner = new Scanner(System.in);
        while (true) { // このループがなければ動く
            String line = scanner.nextLine();
            if ("exit".equals(line)) {
                break;
            }
        }
        System.out.println("System.in finished");
        thread.join();
        System.out.println("joined");
    }
}



このコードでは、

  • before openConnection
  • after openConnection
  • before getInputStream
  • after getInputStream
  • thread finished
  • 標準入力にexitと入力
  • System.in finished
  • joined

の順に表示されることを想定しています。
しかし実行してみると、標準入力に何かしらの入力を与えないとgetInputStreamが実行されず、例えば

  • before openConnection
  • after openConnection
  • before getInputStream
  • 標準入力にexitと入力
  • System.in finished
  • after getInputStream
  • thread finished
  • joined

のようになってしまいます。なおタイムアウトは発生していません。

このように、標準入力を読み込みながら、別のスレッドでウェブ上のデータを取得することは不可能なのでしょうか。
それとも別の記述方法があるのでしょうか。
よろしくお願いします。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2009-02-20 17:52
私の環境では
引用:

なつるぎさんの書き込み (2009-02-20 16:17) より:

  • before openConnection
  • after openConnection
  • before getInputStream
  • after getInputStream
  • thread finished
  • 標準入力にexitと入力
  • System.in finished
  • joined



と動きました。

もし、Threadがロックされているのであれば、ロックオブジェクトが何かを調べましょう。
jconsoleで確認できます。
デバッグモードで起動して標準入力を待っている状態でSuspendしてそれぞれのThreadがどういう状態かを確認するのも手です。
なつるぎ
会議室デビュー日: 2009/02/20
投稿数: 2
投稿日時: 2009-02-22 16:04
nagiseさま。
ご返答ありがとうございます。

http://eclipsewiki.net/eclipse/index.php?jconsoleを参考にjconsoleでプログラムの監視をしてみましたが、こうして起動した場合は想定通りの動作が確認できました。
また、この他に

  • デバッグモードでの起動(Eclipse)
  • コマンドラインからの実行
  • Ubuntu 8.10, Eclipse 3.4.1, IcedTea6 1.3.1で実行

でも試してみましたが、すべて想定通りの動作が確認できました。

どうやら実行条件に問題がありそうですので、もう少し調査を続けてみようと思います。
ありがとうございました。
あすか
ぬし
会議室デビュー日: 2006/07/12
投稿数: 309
投稿日時: 2009-02-22 17:45
全部は面倒なので
thread finished
System.in finished
のみに焦点を合わせて書きます。

thread.start();
した段階で、
thread finished
はいつ出力されてもおかしくない状態になります。

つまり
System.in finished
とどっちが先に出力されるかは
確定されていない事項です。

System.in finished

thread finished
よりも後に出力させたいのであれば
System.in finished
よりも前にjoinする必要があります。
1

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