5

I encounter a problem that threads of my app has locked/blocked when communicate with a remote server using Spring's RestTemplate.

Here is the jstack info of one blocked thread:

"pool-1-thread-8" prio=10 tid=0x00007fbfd012d800 nid=0x27b1 runnable [0x00007fbfd7dfb000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
        - locked <0x00007fbfe40fe1f8> (a java.io.BufferedInputStream)
        at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
        at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1072)
        - locked <0x00007fbfe40fe2f0> (a sun.net.www.protocol.http.HttpURLConnection)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373)
        at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:47)
        at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:32)
        at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:55)
        at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:49)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:489)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
        at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:302)
        at com.xxx.activation.service.action.impl.RestServiceImpl.sendContactRequest(RestServiceImpl.java:37)
        at com.xxx.activation.service.action.impl.SendContactRequestAction.perform(SendContactRequestAction.java:125)
        at com.xxx.activation.service.action.impl.DefaultStateActionService.doAction(DefaultStateActionService.java:75)
        at com.xxx.activation.service.action.impl.ActionProcess$StateActionTask.call(ActionProcess.java:54)
        at com.xxx.activation.service.action.impl.ActionProcess$StateActionTask.call(ActionProcess.java:41)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)


How can i solve this?
Is this related to the readTimeout of java.net.URLConnection?
What's the default values of connectTimeout and readTimeout of underlying socket when using Sring's RestTemplate?

Thanks in advance.

Wuaner
  • 929
  • 2
  • 14
  • 31
  • I think the you don't have permission to connect to the remote socket... – webcoder Jun 27 '14 at 04:07
  • What is the resource your `restTemplate` is trying to access? Is it a thread safe operation to access it? – Nikhil Talreja Jun 27 '14 at 04:18
  • Your stack-trace clearly shows the thread is blocked in `java.net.SocketInputStream.socketRead0`, not `RestTemplate` itself. Do you expect network I/O not to block sometimes? – Raedwald Apr 08 '16 at 12:53
  • See also http://stackoverflow.com/questions/28494203/blocked-thread-while-executing-oracle-procedure-from-java-class – Raedwald Apr 08 '16 at 12:54

2 Answers2

1

If you are using default Rest Template, add read Timeout to the default request Factory currently by default it is SimpleClientHttpRequestFactory

final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setReadTimeout(10_000);  // 10 sec as needed by us
    final RestTemplate restTemplate = new RestTemplate(requestFactory);

If not, then check the http connection readTimeout should not be 0 and assign it a value.

0

A post here describes your problem

Try setting a time out for your REST call and make sure the REST service is up and running. Check if indeed your REST service is trying to fetch a huge amount of information.

Nikhil Talreja
  • 2,754
  • 1
  • 14
  • 20