Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I just can't kill Java thread

I have a thread that downloads some images from internet using different proxies. Sometimes it hangs, and can't be killed by any means.

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();

When it hangs, it freezes at the uc.getInputStream() method. I made a timer which tries to kill the thread if it's run time exceeds 3 minutes. I tried .terminate() the thread. No effect. I tried uc.disconnect() from the main thread. The method also hangs and with it, the main thread. I tried in.close(). No effect. I tried uc=null, in=null hoping for an exception that will end the thread. It keeps running. It never passes the uc.getInputStream() method.

In my last test the thread lasted over 14 hours after receiving all above commands (or various combinations). I had to kill the Java process to stop the thread.

If I just ignore the thread, and set it's instance to null, the thread doesn't die and is not cleaned by garbage collector. I know that because if I let the application running for several days, the Java process takes more and more system memory. In 3 days it took 10% of my 8Gb system RAM.

It is impossible to kill a thread whatever?

like image 343
Adrian Avatar asked Dec 12 '22 22:12

Adrian


2 Answers

It is impossible to kill a thread whatever?

In many cases, yes - especially when the thread is blocked on non-interruptible IO. You might be able to to unblock it by calling uc.getInputStream().close() from another thread. Though that might not be thread safe. HttpUrlConnection also have a setReadTimeout() you should probably set in your case.

like image 177
nos Avatar answered Dec 24 '22 17:12

nos


Try setting uc.setReadTimeout(30000);

like image 36
Jim Blackler Avatar answered Dec 24 '22 18:12

Jim Blackler