4

さまざまなプロキシを使用してインターネットからいくつかの画像をダウンロードするスレッドがあります。時々それはハングし、決して殺すことができません。

public HttpURLConnection uc;
public InputStream in;

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("server", 8080));
URL url = new URL("http://images.com/image.jpg");
uc = (HttpURLConnection)url.openConnection(proxy);
uc.setConnectTimeout(30000);
uc.setAllowUserInteraction(false);
uc.setDoOutput(true);
uc.addRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
uc.connect();

in = uc.getInputStream();

ハングすると、uc.getInputStream()メソッドでフリーズします。実行時間が3分を超えるとスレッドを強制終了しようとするタイマーを作成しました。.terminate()スレッドを試してみました。無効。uc.disconnect()メインスレッドから試してみました。メソッドもハングし、メインスレッドもハングします。やってみin.close()ました。無効。スレッドを終了する例外を期待して、uc=null試してみました。in=null走り続けます。メソッドを渡すことはありませんuc.getInputStream()

私の最後のテストでは、上記のすべてのコマンド(またはさまざまな組み合わせ)を受け取った後、スレッドは14時間以上続きました。スレッドを停止するには、Javaプロセスを強制終了する必要がありました。

スレッドを無視し、そのインスタンスをnullに設定すると、スレッドは停止せず、ガベージコレクターによってクリーンアップされません。アプリケーションを数日間実行させると、Javaプロセスがますます多くのシステムメモリを消費するためです。3日間で、8GbシステムRAMの10%が必要になりました。

スレッドを殺すことは不可能ですか?

4

4 に答える 4

5

スレッドを殺すことは不可能ですか?

多くの場合、そうです。特に、中断できないIOでスレッドがブロックされている場合はそうです。uc.getInputStream().close()別のスレッドから呼び出すことで、ブロックを解除できる場合があります。それはスレッドセーフではないかもしれませんが。HttpUrlConnectionにはsetReadTimeout()もあり、おそらくあなたのケースで設定する必要があります。

于 2010-04-14T12:35:28.400 に答える
4

設定してみてくださいuc.setReadTimeout(30000);

于 2010-04-14T12:33:33.210 に答える
4

読み取りタイムアウト(他の応答で言及されている)を設定するとともに、スレッドを中断してみましたか?

于 2010-04-14T14:27:07.077 に答える
0

いいえ、できません。外部からスレッドを強制終了することは、本質的に危険な操作です。

あなたができることは、スレッドを自発的に閉じるようにすることです。タイムアウトを超えたときに自動的に終了するようにダウンロードスレッドを記述します。

于 2010-04-14T12:36:42.057 に答える