前言


先声明,这里我没有试图去列举所有出现这种问题的情况,只针对我自己做过的项目遇到的问题。
问题代码如下:
首先通过HttpURLConnection创建链接:

        URL url = new URL( servletUrl );HttpURLConnection connection = (HttpURLConnection)url.openConnection();trustModifier.relaxHostChecking( connection );connection.setDoOutput( true );connection.setRequestMethod( REQUEST_METHOD );

然后在执行了send之后,等待远端读取,并返回,注意这里的代码,用的是URLConnection,然后从socket上读取数据,并没有用到HttpURLConnection.getResonpseCode()

    public void handleResponse( URLConnection connection ) throws IOException{try (BufferedReader connectionBuffer =new BufferedReader( new InputStreamReader( connection.getInputStream(), UTF_8 ) )){String response;while( (response = connectionBuffer.readLine()) != null ){logger.debug( response );}}}

当你的并发操作很多,线程切换很频繁,cpu load很高的时候,就会出现SocketInputStream.socketRead0的问题:

13:04:54,193 INFO  [stdout] (EJB default - 1)   at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.7.0_25]13:04:54,193 INFO  [stdout] (EJB default - 1)   at java.net.SocketInputStream.read(SocketInputStream.java:150) ~[na:1.7.0_25]13:04:54,193 INFO  [stdout] (EJB default - 1)   at java.net.SocketInputStream.read(SocketInputStream.java:121) ~[na:1.7.0_25]13:04:54,194 INFO  [stdout] (EJB default - 1)   at sun.security.ssl.InputRecord.readFully(InputRecord.java:442) ~[na:na]13:04:54,195 INFO  [stdout] (EJB default - 1)   at sun.security.ssl.InputRecord.read(InputRecord.java:480) ~[na:na]13:04:54,195 INFO  [stdout] (EJB default - 1)   at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927) ~[na:na]13:04:54,196 INFO  [stdout] (EJB default - 1)   at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884) ~[na:na]13:04:54,196 INFO  [stdout] (EJB default - 1)   at sun.security.ssl.AppInputStream.read(AppInputStream.java:102) ~[na:na]13:04:54,196 INFO  [stdout] (EJB default - 1)   at java.io.BufferedInputStream.fill(BufferedInputStream.java:235) ~[na:1.7.0_25]13:04:54,196 INFO  [stdout] (EJB default - 1)   at java.io.BufferedInputStream.read1(BufferedInputStream.java:275) ~[na:1.7.0_25]13:04:54,197 INFO  [stdout] (EJB default - 1)   at java.io.BufferedInputStream.read(BufferedInputStream.java:334) ~[na:1.7.0_25]13:04:54,197 INFO  [stdout] (EJB default - 1)   at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:633) ~[na:na]13:04:54,197 INFO  [stdout] (EJB default - 1)   at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579) ~[na:na]13:04:54,197 INFO  [stdout] (EJB default - 1)   at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322) ~[na:na]13:04:54,197 INFO  [stdout] (EJB default - 1)   at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) ~[na:na]

原因


使用HttpURLConnection的步骤是先实例化一个URL对象,通过URL的openConnection实例化HttpURLConnection对象。然后设置参数,注意此时并没有发生连接。真正发生连接是在获得流时即conn.getInputStream这一句时,这点跟TCP Socket是一样的。并非阻塞在ServerSocket.accept()而是阻塞在获取流。所以在获取流之前应该设置好所有的参数。特别是timeout参数。


**做个总结,进行远程通信时,在客户程序中,线程在以下情况可能进入阻塞状态:**请求与服务器建立连接时,即当线程执行Socket的带参数的构造方法,或执行Socket的connect()方法时,会进入阻塞状态,直到连接成功,此线程才从Socket的构造方法或connect()方法返回。
线程从Socket的输入流读入数据时,如果没有足够的数据,就会进入阻塞状态,直到读到了足够的数据,或者到达输入流的末尾,或者出现了异常,才从输入流的read()方法返回或异常中断。输入流中有多少数据才算足够呢?这要看线程执行的read()方法的类型:1. int read():只要输入流中有一个字节,就算足够。2. int read(byte[] buff):只要输入流中的字节数目与参数buff数组的长度相同就算足够。3. String readLine():只要输入流中有一行字符串,就算足够。值得注意的是InputStream类并没有readLine()方法,在过滤流BufferedReader类中才有此方法。线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流的write()方法返回或异常中断。
当调用Socket的setSoLinger()方法设置了关闭Socket的延迟时间,那么当线程执行Socket的close()方法时,会进入阻塞状态,直到底层Socket发送完所有剩余数据,或者超过了setSoLinger()方法设置的延迟时间,才从close()方法返回。
在服务器程序中,线程在以下情况可能会进入阻塞状态:线程执行ServerSocket的accept()方法,等待客户的连接,直到接收到了客户连接,才从accept()方法返回。
线程从Socket的输入流读入数据时, 如果输入流没有足够的数据,就会进入阻塞状态。
线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流的write()方法返回或异常中断。###解决方案
---
1, 通过setTimeout可以解决问题
```java
//设置connection timeout为3秒
connection.setConnectionTimeout(3 * 1000)
//设置read timeout为5秒
connection.setReadTimeout(5 * 1000)2,通过一个connection的监控线程,查询定时清除掉已经expired或者idle的链接。<div class="se-preview-section-delimiter"></div>```java
public static class IdleConnectionMonitorThread extends Thread {private final HttpClientConnectionManager connMgr;private volatile boolean shutdown;public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {super();this.connMgr = connMgr;}@Overridepublic void run() {try {while (!shutdown) {synchronized (this) {wait(5000);// Close expired connectionsconnMgr.closeExpiredConnections();// Optionally, close connections// that have been idle longer than 30 secconnMgr.closeIdleConnections(30, TimeUnit.SECONDS);}}} catch (InterruptedException ex) {// terminate}}public void shutdown() {shutdown = true;synchronized (this) {notifyAll();}}}

SocketInputStream.socketRead0 导致线程hangs的解决方案相关推荐

  1. Java线上问题排障:Linux内核bug引发JVM死锁导致线程假死

    Java本质上还是离不开操作系统,一来Java源码是用C/C++实现的,二来java进程还是需要依附于操作系统和硬件资源,有时候一些问题是操作系统级别导致的,下面的整个事件是源自一则真实的线上案例. ...

  2. SimpleDateFormat类的线程安全问题和解决方案

    摘要:我们就一起看下在高并发下SimpleDateFormat类为何会出现安全问题,以及如何解决SimpleDateFormat类的安全问题. 本文分享自华为云社区<SimpleDateForm ...

  3. 为什么HashMap线程不安全?以及实现HashMap线程安全的解决方案

    一.为什么HashMap线程不安全? 原著参考 1.JDK1.7 扩容引发的死循环和数据丢失 (1).当前jdk1.7版本的HashMap线程不安全主要是发生在扩容函数中,其中调用了HshMap的tr ...

  4. 导致线程死锁的原因?怎么解除线程死锁

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 一.导致线程死锁的原因 多个线程同时被阻塞,它们中的一个或者全部都在 ...

  5. C# 在异步中使用HttpWebRequest出现的“正在终止线程”错误的解决方案

    C# 在异步中使用HttpWebRequest出现的"正在终止线程"错误的解决方案 参考文章: (1)C# 在异步中使用HttpWebRequest出现的"正在终止线程& ...

  6. 因滚动条出现而导致页面晃动的解决方案

    因滚动条出现而导致页面晃动的解决方案 这两天因为oa主页为了消除晃动的影响给body下的div加了一个{min-height:960},可是产品对底部出现的大片空白不满意,而且如果换了超大屏幕这个最小 ...

  7. Ubuntu下安装Wine可能导致假死问题解决方案

    Ubuntu下安装Wine可能导致假死问题解决方案 出现问题 在使用Ubuntu使用apt-get install wine时,导致下载处于假死状态,不论将dpkg命令杀死,还是按照提示sudo ap ...

  8. java多线程安全解决方案_《Java多线程编程核心技术(第2版)》 —1.2.8 实例变量共享造成的非线程安全问题与解决方案...

    1.2.8 实例变量共享造成的非线程安全问题与解决方案 自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程之间交互时是很重要的技术点. 1.不共享数据的情况 不共享数据的情况如图 ...

  9. 谈谈spring-boot不同包结构下,同样的类名冲突导致服务启动失败解决方案

    谈谈spring-boot不同包结构下,同样的类名冲突导致服务启动失败解决方案 参考文章: (1)谈谈spring-boot不同包结构下,同样的类名冲突导致服务启动失败解决方案 (2)https:// ...

最新文章

  1. 用gensim学习word2vec
  2. 【小练习】“表格”制作及答案
  3. rocm平台_痛击NV CUDA!AMD ROCm开放计算平台瓜熟蒂落
  4. istio api_Istio的网络API解释了
  5. linux ssh禁止用户访问任何目录,怎么限制远程ssh用户访问特定的文件
  6. json同一个参数不同类型_js基础之变量类型
  7. (转)【重磅】无监督学习生成式对抗网络突破,OpenAI 5大项目落地
  8. CentOS 7安装zabbix-agent 5.0报错:依赖检测失败:libpcre.so.0()(64bit)/获取GPG密钥失败解决
  9. mysql存储php数组_mysql数据库存储PHP数组、对象的方法
  10. 艺术字体图标设计软件Art Text 4 for Mac
  11. 水晶报表自定义函数进行代码重用 -日期大写
  12. 阿里云商标智能注册申请图文教程(亲踩坑)
  13. 自考CISSP信息分享
  14. 马未都说收藏:陶瓷篇-常见瓷器器形分类
  15. GB50016计算机房设计规定,为什么GB50016-2014《建筑设计防火规范》不包含防排烟系统实施规定?...
  16. OJ笔记 18939 最长单词
  17. AtCoder2362 - Splatter Painting - DFS+思维
  18. Lumerical官方案例、FDTD时域有限差分法仿真学习(九)——布拉格光栅(Bragg gratings)
  19. 扫描识别行驶证的软件技术
  20. 使用URLRewriter进行URL重写失效

热门文章

  1. 看顶级渣男如何邀约100个女朋友(一)
  2. 爬虫学习笔记--爬取静态网页
  3. JavaScrapt朝花夕拾
  4. 卓有成效的管理者——第5章 要事优先
  5. WEB测试应该注意哪些地方,怎样才能做好WEB测试
  6. 达梦数据库 年月周查询
  7. 企业上云的动力是什么
  8. Qt配置OpenCV环境变量
  9. 耳中明珠绾臂金环:古代女子私妆的故事(组图)
  10. FTDI FT2232H USB TO JTAG学习笔记(一)基础概念