BIO 详解
调用者主动等待调用的结果
简介
早期的jdk中,采用BIO通信模式:
通常有一个acceptor(消费者) 去负责监听客户端的连接。
它接收到客户端的连接请求之后为每个客户端创建一个线程进行链路处理,处理完成之后,线程销毁。
一个客户端连接,对应一个处理线程。他们之间的对应关系是 1:1。
由于客户端连接和服务端的处理之间的对应关系是1:1,如果遇到任务比较大,处理比较慢。
或者并发量比较大的情况下,系统会创建大量的线程。从而导致服务器线程暴增,性能急剧下降,甚至宕机。
客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
try {
//创建连接
socket = new Socket("127.0.0.1", 8080);
//输出流:发送数据
out = new PrintWriter(socket.getOutputStream(), true);
out.println("发送数据");
//输入流:接收数据
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//阻塞:未收到数据就等在这里
String resp = in.readLine();
System.out.println("回应:" + resp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
out.close();
out = null;
}
}
}
服务端
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
//创建服务端
serverSocket = new ServerSocket(8080);
Socket socket = null;
while (true) {
//从socket的队列中获取socket的连接
//相当于一个消费者
///当前的线程阻塞在accept方法上面。该方法一直阻塞,除非获取到socket连接返回
socket = serverSocket.accept();
// 获得到socket连接之后,分配线程任务进行处理
new Thread(new Handler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
serverSocket = null;
}
}
}
}
处理线程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Handler implements Runnable {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
//输入流:接收数据
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
//接收数据
String receive = null;
//输出流:发送数据
out = new PrintWriter(this.socket.getOutputStream(), true);
//回应结果
String currentTime = null;
while (true) {
//输入流:读取数据的部分是阻塞的
//由于使用的是阻塞IO,那么read方法一直处于阻塞状态,要等到数据传送完成才结束(返回-1)
//1,内核程序从网卡中把数据读取到内核空间中,是一直阻塞的。
//2,用户程序把内核空间的数据复制到用户空间的过程,是阻塞的。
//这两个过程中,对应的程序部分就是read方法的阻塞
receive = in.readLine();
if (receive == null) {
break;
}
System.out.println(receive);
//输出流:输出数据
currentTime = "收到";
out.println(currentTime);
}
} catch (IOException e) {
e.printStackTrace();
if (in != null) {
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (out != null) {
out.close();
out = null;
}
}
}
}
BIO 详解的更多相关文章
- redis BIO详解
BIO即background I/O service,后台I/O服务,是redis的aof持久化后台服务. redis把阻塞的同步I/O操作交给后台I/O服务来完成:close和fsync. clos ...
- 详解tomcat的连接数与线程池
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...
- 详解Tomcat的连接数和线程池
转: https://www.cnblogs.com/kismetv/p/7806063.html#t11 前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须 ...
- Tomcat记录-tomcat常用配置详解和优化方法(转载)
常用配置详解 1 目录结构 /bin:脚本文件目录. /common/lib:存放所有web项目都可以访问的公共jar包(使用Common类加载器加载). /conf:存放配置文件,最重要的是serv ...
- Python 19 Django 详解
本节概要 Django详解 前言 有一部分原因是,确实djando的课程有点多:并且,最近又在研究利用python做数据分析时间上耽误了.所以楼主讲所有的课程全部重新观看了一遍,再来撰写博客,其实说起 ...
- 详解 Tomcat 的连接数与线程池
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server. ...
- Java性能分析之线程栈详解与性能分析
Java性能分析之线程栈详解 Java性能分析迈不过去的一个关键点是线程栈,新的性能班级也讲到了JVM这一块,所以本篇文章对线程栈进行基础知识普及以及如何对线程栈进行性能分析. 基本概念 线程堆栈也称 ...
- 详解tomcat连接数和线程数
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...
- Java网络编程和NIO详解3:IO模型与Java网络编程模型
Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...
随机推荐
- XX Russia Team Open, High School Programming Contest St Petersburg, Barnaul, Tbilisi, Almaty, Kremenchug, November 30, 2019
ContestLink easy: AFI medium-easy: BDH medium: CGKL ???: EJ A. Attractive Flowers 签到. B. Blocking th ...
- sanic连接mongo
方法一: #没有密码,就是没有用户和用户密码 settings={"MOTOR_URI":"mongodb://127.0.0.1:27017/zzy"} ap ...
- S1#Python之shebang
点1 - Python之shebang 一. shebang 在计算机科学中,Shebang是一个由井号和叹号构成的字符串行,其出现在文本文件的第一行的前两个字符. 在文件中存在Shebang的情况下 ...
- 实体类Json串转成DataTable
private DataTable GetJsonToDataTable(string json) { List<Object_DeclareInfo> arrayList = JsonC ...
- tftp 服务器的配置
如果用下面一条命令能够看到服务已经启动, 则不用安装, 否则需要按 1 或 2 点安装 tftp-server 服务器. [arm@localhost arm]#netstat -a | grep t ...
- 10_PAE_非PAE
前置知识: 在 windows 中 保护模式 有两种模式: 段保护 和 页保护 段保护 主要体现在 段选择子上:但是数据段.代码段.栈段等采用的都是4GB平坦模式,段的特征并没有那样展现.所以具体的保 ...
- Boost.Interprocess
https://github.com/svebert/InterprocessMsg 好像消息队列
- mysql组合查询
使用UNION 多数SQL查询都只包含一个或多个表中返回数据的单条SELECT语句.MySQL也允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回.这些组合查询通常称为并(uni ...
- input 实现一次性上传文件
在实际项目中可能会用到,上传多个文件请求一次接口,因此,主要代码 $('#tabList').on('click','.resetWorkStatus',function(){ var that = ...
- FTT & NTT & 分治FFT
FFT study from: http://www.orchidany.cf/2019/02/19/FFT1/ https://www.cnblogs.com/zwfymqz/p/8244902.h ...