【发布时间】:2011-02-07 21:38:04
【问题描述】:
我有一个线程使用不同的代理从互联网下载一些图像。 有时它会挂起,并且无法以任何方式杀死。
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%。
杀死一个线程是不可能的?
【问题讨论】:
-
你必须在打开调试器时在脖子上戴一点大蒜,四处洒上圣水,然后用木牛排敲打进程的心脏,最后砍下它的头并烧掉它遗迹。这是唯一确定的方法。 (当然,或者从轨道上对其进行核打击。)
-
@Jeffrey L Whitledge:是的,这样做然后你发现自己有 20 多个线程冻结在死锁中,因为你刚刚杀死的线程在持有没有人可以释放的锁的钥匙时被焚毁因为对象处于不一致的状态。
标签: java multithreading kill