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=nullin=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 回答