网络I/O模型--02阻塞模式(多线程)
当服务器收到客户端 X 的请求后(读取到所有请求数据后),将这个请求送入一个独立线程进行处理,然后主线程继续接收客户端 Y 的请求。
客户端一侧也可以使用一个子线程和服务器端进行通信。这样客户端主线程的其他工作就不受影响了,当服务器端有响应信息时再由这个子线程通过监听模式/观察模式或者类似的其他设计模式通知主线程。
服务端
package testBlockSocket; import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; // 通过多线程的方式处理socket的连接
public class SocketServer2MiltiThread {
private final static Logger LOGGER = LoggerFactory.getLogger(SocketServer2MiltiThread.class); public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
try {
while (true) {
Socket socket = serverSocket.accept();
// 业务处理过程可以交给一个线程,不过线程的创建很耗资源
// 最终改变不了, accept () 只能在被阻塞的情况一个一个接收 Socket
SocketServerThread socketServerThread = new SocketServerThread(socket);
Thread thread = new Thread(socketServerThread);
thread.start();
}
} catch (Exception e) {
SocketServer2MiltiThread.LOGGER.error(e.getMessage(), e);
} finally {
if (serverSocket != null) {
serverSocket.close();
// 当然 , 接收到客户端的 Socket 后 , 业务的处理过程可以交给一个线程来做
}
}
} } class SocketServerThread implements Runnable {
private final static Logger LOGGER = LoggerFactory.getLogger(SocketServerThread.class); private Socket socket; public SocketServerThread(Socket socket) {
this.socket = socket;
} @Override
public void run() {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// 下面我们收取信息
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
Integer sourcePort = socket.getPort();
int maxLen = 1024;
byte[] contextBytes = new byte[maxLen];
// 同样无法改变 read 方法被阻塞,直到操作系统有数据准备好的现象
int realLen = inputStream.read(contextBytes, 0, maxLen);
String message = new String(contextBytes, 0, realLen);
LOGGER.info("服务器收到来自于端曰 :" + sourcePort + " 的信息:" + message);
// 下面开始发送响应信息
outputStream.write("因发响应信息 !".getBytes());
} catch (Exception e) {
SocketServerThread.LOGGER.error(e.getMessage(), e);
} finally {
// 试图关闭连接
try {
inputStream.close();
outputStream.close();
socket.close();
} catch (Exception e) {
SocketServerThread.LOGGER.error(e.getMessage(), e);
}
}
} }
1)虽然在服务器端,接收到数据后的处理交给了 一个独立线程进行,但是操作系 统通知accept()的方式还是单个线程运行的 。 也就是说,实际上是服务器接收到数据报文后的“业务处理过程”可以应用多线程技术,但是数据报文的接收还是需要一个接一个地来,从以上的示例代码和其调试过程我们都可以明确看到这一点。
2)在 Linux 系统中,可以创建的线程是有限的。可以通过 cat /proc/sys/kernel/threads-max命令查看可以创建的最大线程数。当然这个值可以更改,但是参与调度的线程数量越大, CPU 用在线程间切换所需的时间也就越长,用来处理真正业务的资源也就越少。CPU 线程状态间切换的性能消耗是非常巨大的,后文我们会对这个描述给出相应的实例以便将这个感性的认识具体化,帮助读者真正认识线程间状态切换的性能代价 。
3)创建一个线程是有较大的资源消耗的 。 例如 NM 创建一个线程时,即使这个线程不做任何工作,JVM都会分配一个独立线程技空间(不同 JDK 版本默认的大小不一样〉 。虽然它可以通过“-Xss ”参数进行大小调整,但这不影响 CPU 一级、 二次缓存中的数据出现线程数据的换入/换出 。
总结:
阻塞模型的问题关键不在于是否使用了多线程(包括线程池)处理并发请求,而在于 accept()、 read()的操作点都被阻塞了 。
完
网络I/O模型--02阻塞模式(多线程)的更多相关文章
- 网络I/O模型--01阻塞模式(普通)
很长一段时间内,大多数网络通信方式都是阻塞模式,即: · 客户端 向服务器端发出请求后,客户端会一直处于等待状态(不会再做其他事情),直到服务器端返回结果或者网络出现问题 . · 服务器端同样如此,当 ...
- Socket 阻塞模式和非阻塞模式
阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...
- 网络IO模型与Reactor模式
一.三种网络IO模型: 分类: BIO 同步的.阻塞式 IO NIO 同步的.非阻塞式 IO AIO 异步非阻塞式 IO 阻塞和同步的概念: 阻塞:若读写未完成,调用读写的线程一直等待 非阻塞:若读写 ...
- 简明网络I/O模型---同步异步阻塞非阻塞之惑
转自:http://www.jianshu.com/p/55eb83d60ab1 网络I/O模型 人多了,就会有问题.web刚出现的时候,光顾的人很少.近年来网络应用规模逐渐扩大,应用的架构也需要随之 ...
- 网络I/O模型---同步异步阻塞非阻塞之惑
网络I/O模型 人多了,就会有问题.web刚出现的时候,光顾的人很少.近年来网络应用规模逐渐扩大,应用的架构也需要随之改变.C10k的问题,让工程师们需要思考服务的性能与应用的并发能力. 网络应用需要 ...
- UNIX网络编程读书笔记:I/O模型(阻塞、非阻塞、I/O复用、信号驱动、异步)
I/O模型 UNIX下可用的5种I/O模型: (1)阻塞I/O (2)非阻塞I/O (3)I/O复用(select和poll) (4)信号驱动I/O(SIGIO) (5)异步I/O 对于一个套接口上的 ...
- 网络IO模型 非阻塞IO模型
网络IO模型 非阻塞IO模型 同步 一件事做完后再做另一件事情 异步 同时做多件事情 相对论 多线程 多进程 协程 异步的程序 宏观角度:异步 并发聊天 阻塞IO 阻塞IO的问题 一旦阻塞就不能做其他 ...
- TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍
首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...
- 转:PHP中实现非阻塞模式
原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...
随机推荐
- Part15 – 前端之jQuery
本节内容 jQuery 一.jQuery jQuery是对DOM的封装 jQuery 中文在线文档:http://jquery.cuishifeng.cn/ 模块(Python) <--> ...
- iOS-UIScrollView内容复用【实现两个试图的复用】
前言 这里说的内容复用,是指添加到 ScrollView 里面的试图是同一个模型:比如,我需要在 ScrollView 上添加100个 xkView(其他封装好的VC.UIView),每次滑动 Scr ...
- 解决后台json数据返回的字段需要替换的问题
有时候后台json数据返回的字段含有“id”,也有可能是有时候为了减少代码的冗余,两页面之间只是数据模型个别属性的区别,所以这时候最好是用到模型属性的替换,用新的属性替换返回的json数据的字段.这里 ...
- Java爬虫——Gecco简单入门程序(根据下一页一直爬数据)
为了完成作业,所以学习了一下爬虫Gecco,这个爬虫集合了以往所有的爬虫的特点,但是官方教程中关于Gecco的教程介绍的过于简单,本篇博客是根据原博客的地址修改的,原博客中只有程序的截图,而没有给出一 ...
- Linux实用指令
Linux实用指令 Rpm&Yum 一种用于互联网下载包的打包和安装工具,它包含某些Linux分发版中,它生产具有 .rpm 扩展名的文件.RPM 是 RedHat Package Man ...
- SQLServer2005重建索引
今天发现一个页面运行很慢,用SQL Server Profiler抓出了一条运行时间为12s的sql ) and wfinstance is not null and wftbrq>='2016 ...
- MBIST:用于嵌入式存储器的可测试设计技术
MBist技术可以自动实现存储器单元或阵列的RTL级内建自测试电路,MBIST的EDA工具支持多种测试算法的自动实现,可针对一个或多个内嵌存储器自动创建BIST逻辑,并完成BIST逻辑与存储器的连接, ...
- 通用数据库连接池-C3PO
C3PO是一个开放源代码的JDBC数据连接池实现项目,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.开源项目在使用:Hibernate,Spring,MYSQL等. 下载: h ...
- Chrome 谷歌如何快速实现跨域
第一步:在你的E盘或者其他盘新建一个文件夹,命名为:E:\MyChromeDevUserData 第二步:找到你的谷歌浏览器快捷图标,鼠标右键选择属性,出现以下界面: 第三步:在目标选项的最后添加: ...
- 前端神器之Sublime Text2/3简单明了使用总结
为什么叫神器呢? 我总结如下: 第一:也是最重要的,它占内存很小(就如同notepad++那般迅速打开,所以那款其实也不错~).一般IDE比如WebStorm(它也是一款神器来着),Aptana(也比 ...