`
san_yun
  • 浏览: 2638596 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

socket InputStream available()lock的问题

 
阅读更多

socket InputStream读取数据的问题记录一文中介绍通过input.available()检测是否有可读的字节,上线之后发现服务器load过高,通过jstack发现大量线程都lock在在SocketInputStream.available()上,见截图:



 

之前以为input.available()会很耗时,通过打点发现原来是调用input.available()过于频繁导致:



 

解决这个问题有一个方案,不要调用input.available(),通过bufferInputStream不停的尝试read(),通过研究netty的代码发现有更好的方案,先检测input.available(),如果数据没有准备好,则挂起不占用cpu,这种方案是通过PushbackInputStream实现的:

 

public String readLine(int length) throws IOException {
		String buf = "";
		PushbackInputStream input = new PushbackInputStream(socket.getInputStream(), 1);
		int index = 0;
		while (true) {
			index = buf.indexOf("\r\n");
			if (index >= 0) {
				break;
			}
			int bytesToRead = Math.min(input.available(), length);
			if(bytesToRead>0){
			    byte[] data = new byte[bytesToRead];
	            input.read(data);
	            String line = new String(data, Protocol.ENCODE);
	            buf += line;    
			}else{
			    int b = input.read(); //此操作会阻塞,直到有数据被读到
                if (b < 0) {
                    break;
                }
                input.unread(b);
                continue;
			}
		}
		return buf.substring(0, index);
	}

 

 修复之后的情况:



 

后续发现还有问题:



 

 

  • 大小: 196.8 KB
  • 大小: 208.5 KB
  • 大小: 203.8 KB
  • 大小: 177.4 KB
  • 大小: 183.7 KB
分享到:
评论

相关推荐

    SocketInputStream.java

    深入剖析tomcat第三章SocketInputStream源码 * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/StringManager.java,v 1.2 2001/07/22 20:25:14 pier Exp $ * $Revision: 1.2...

    Socket中InputStream的read方法的阻塞特性

    Socket中的InputStream的`read`方法是Java网络编程中一个核心的概念,它在处理客户端与服务器之间的数据传输时起着至关重要的作用。`read`方法的阻塞特性是其设计的一个重要特点,也是理解多线程和并发编程的关键点...

    SocketInputStream.rar_网络编程_Unix_Linux_

    SocketInputStream是Java编程语言中用于网络编程的一个重要组件,它属于Java套接字API的一部分,主要负责从套接字连接中读取字节流。在Unix和Linux操作系统环境下,网络编程通常涉及到进程间的通信,而Socket...

    java InputStream读取数据问题

    在Java编程中,`InputStream`是Java I/O流的基础类,用于从各种输入源读取数据。...对于压缩包中的`socketTest`文件,可能是用于测试网络数据传输的Socket编程示例,与`InputStream`在处理网络数据流时的应用紧密相关。

    springboot 解决InputStream只能读取一次的问题

    // 实现其他ServletInputStream的方法,如 available(), markSupported(), mark(int), reset() } } ``` 在这个例子中,我们创建了一个名为`RepeatableHttpServletRequest`的类,它继承自`...

    Java中InputStream类.pdf

    例如,`FileInputStream`可以从文件系统读取数据,`SocketInputStream`可以从网络连接读取数据。在处理这些数据流时,可以利用`InputStream`提供的方法进行读取、跳过、标记和重置操作。 总结,`InputStream`在Java...

    inputstream读取数据的问题

    inputstream读取数据的问题,对你的file的帮组是很大的。

    java socket长连接中解决read阻塞的3个办法

    然而,使用Socket进行数据传输时,可能会遇到`read()`方法阻塞的问题,导致程序挂起,无法继续执行。为了解决这个问题,通常有以下三种策略: 1. **约定数据长度**: 在数据包的头部添加一个字段来指定数据的长度...

    android socket通信实例程序

    InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int length = inputStream.read(buffer); String receivedData = new String(buffer, 0, length); // 处理接收到的数据...

    INPUTSTREAM

    `InputStream` 是所有字节输入流的父类,包括文件输入流 `FileInputStream`、内存输入流 `ByteArrayInputStream` 和网络输入流 `SocketInputStream` 等。通过继承 `InputStream`,子类可以实现特定类型的输入流,...

    Socket模拟服务器_Socket模拟服务器_

    通过Socket对象,我们可以获取InputStream,用来读取客户端发送的数据。常见的做法是使用BufferedReader配合InputStreamReader进行读取。 ```java InputStream clientInputStream = clientSocket.getInputStream(); ...

    基于socket的文件传输

    客户端则相反,它接收来自服务器的数据,通过Socket的InputStream读取,并用FileOutputStream将数据写入本地文件,从而实现文件的传输。 以下是实现这一过程的主要步骤: 1. **服务器端**: - 创建ServerSocket并...

    将输出流OutputStream转化为输入流InputStream的方法

    在Java中,它们是Java.io包下的基础类,提供了多种子类来处理不同类型的输出和输入操作,如`FileOutputStream`和`FileInputStream`用于文件操作,`SocketOutputStream`和`SocketInputStream`用于网络通信等。...

    Android开发,Socket Client端和Socket Server端数据发送和接收

    - **关闭资源**:在完成数据交换后,应关闭Socket、InputStream和OutputStream,避免资源浪费。 9. **示例代码** - Server端示例: ```java ServerSocket serverSocket = new ServerSocket(12345); Socket ...

    JAVA Socket 网络编程教程

    1. InputStream和OutputStream:Socket提供了InputStream和OutputStream的子类,如SocketInputStream和SocketOutputStream,用于读写网络数据。 2. BufferedReader和PrintWriter:通常使用BufferedReader读取Socket...

    java socket通信实现

    3. InputStream和OutputStream:Socket提供的InputStream和OutputStream是处理数据传输的基础。服务端和客户端可以通过这些流对象读写数据,实现双方的数据交换。 三、服务端实现 服务端程序主要包含以下步骤: 1. ...

    java socket教程java socket教程

    例如,Socket的getInputStream()和getOutputStream()方法分别返回InputStream和OutputStream实例,可用于读写操作。 1. 输入流:用于从Socket读取数据,常见的有DataInputStream,可读取基本类型数据。 2. 输出流:...

    利用socket连续发送与连续接收数据

    每次接收数据使用`Socket`的`InputStream`,如`Socket.getInputStream().read()`。 - 当接收完三次数据后,服务器可以将处理结果通过`Socket`的`OutputStream`写回给客户端。 2. **客户端实现:** - 创建`Socket`...

    Android Socket简单使用

    InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); // 读取服务器返回的数据 String serverResponse = dataInputStream.readUTF(); ...

    android socket通讯例子

    InputStream inputStream = socket.getInputStream(); // 发送数据 outputStream.write("Hello, Server!".getBytes()); // 接收数据 int received = inputStream.read(); ``` 在Android中,还需要处理权限问题。在...

Global site tag (gtag.js) - Google Analytics