我有一个线程,使用不同的代理从互联网下载一些图像。 有时会挂起,不能以任何方式杀死。
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%。
无论如何杀死一个线程都是不可能的?
答案 0 :(得分:5)
无论如何杀死一个线程都是不可能的?
在许多情况下,是的 - 特别是当线程在不可中断的IO上被阻止时。
您可以通过从另一个线程调用uc.getInputStream().close()
来取消阻止它。虽然这可能不是线程安全的。 HttpUrlConnection也有一个setReadTimeout()你应该在你的情况下设置。
答案 1 :(得分:4)
尝试设置uc.setReadTimeout(30000);
答案 2 :(得分:4)
除了设置读取超时(在其他回复中提到)之外,您是否尝试中断线程?
答案 3 :(得分:0)
不,你不能。从外部杀死一个线程本身就是不安全的操作。
你可以做的是让线程自愿关闭。编写下载线程,以便在超过超时时自行终止。