nio

Java NIO使用及原理分析 (四)

生来就可爱ヽ(ⅴ<●) 提交于 2020-02-13 20:48:27
在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O。通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据。同样,写入调用将会阻塞直至数据能够写入。传统的Server/Client模式会基于TPR(Thread per Request),服务器会为每个客户端请求建立一个线程,由该线程单独负责处理一个客户请求。这种模式带来的一个问题就是线程数量的剧增,大量的线程会增大服务器的开销。大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大数量,这由带来了新的问题,如果线程池中有200个线程,而有200个用户都在进行大文件下载,会导致第201个用户的请求无法及时处理,即便第201个用户只想请求一个几KB大小的页面。传统的 Server/Client模式如下图所示: NIO中非阻塞I/O采用了基于Reactor模式的工作方式,I/O调用不会被阻塞,相反是注册感兴趣的特定I/O事件,如可读数据到达,新的套接字连接等等,在发生特定事件时,系统再通知我们。NIO中实现非阻塞I/O的核心对象就是Selector,Selector就是注册各种I/O事件地 方,而且当那些事件发生时,就是这个对象告诉我们所发生的事件,如下图所示: 从图中可以看出,当有读或写等任何注册的事件发生时

java NIO基础

别来无恙 提交于 2020-02-13 20:47:49
Java I/O 分类 磁盘操作:File 字节操作:InputStream 和 OutputStream 字符操作: Writer 和 Reader 对象操作:Serializable 网络操作:Socket 新的输入/输出:NIO NIO (1)通道(Channel) 通道 Channel 是对原 I/O 包中的流的模拟,Channel 本身不能直接访问数据,Channel 只能与Buffer 进行交互。 通道与流的不同之处在于,流只能在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类),而通道是双向的,可以用于读、写或者同时用于读写。 通道包括以下类型: FileChannel:从文件中读写数据; DatagramChannel:通过 UDP 读写网络中数据; SocketChannel:通过 TCP 读写网络中数据; ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。 (2)缓冲区(Buffer) 发送给一个通道的所有数据都必须首先放到缓冲区中,同样地,从通道中读取的任何数据都要先读到缓冲区中。也就是说,不会直接对通道进行读写数据,而是要先经过缓冲区。 缓冲区实质上是一个数组,但它不仅仅是一个数组。缓冲区提供了对数据的结构化访问

java nio多路复用 selector

房东的猫 提交于 2020-02-12 19:36:59
文章目录 多路复用selector 多路复用 unix内核中的select/epoll/poll select poll epoll 代码样例 多路复用selector 多路复用 I/O多路复用,I/O是指网络I/O, 多路指多个TCP连接(即socket或者channel),复用指复用一个或几个线程;简单来说:就是使用一个或者几个线程处理多个TCP连接;最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程;多路复用分为三种形式select/epoll/poll,在 Java 中, Selector 这个类是 select/epoll/poll 的外包类 , 在不同的平台上, 底层的实现可能有所不同, 但其基本原理是一样的, 其原理图如下所示: unix内核中的select/epoll/poll select 函数: int select ( int maxfdp1 , fd_set * readset , fd_set * writeset , fd_set * exceptset , const struct timeval * timeout ) 返回值:就绪描述符的数目,超时返回 0 ,出错返回 - 1 maxfdp1:描述符个数 * readset、 * writeset、 * exceptset:读、写和异常条件的描述字 * timeout

BIO NIO AIO (NIO详解)

ⅰ亾dé卋堺 提交于 2020-02-11 22:48:50
文章目录 BIO NIO 一、基本知识 二、NIO编程流程 1. NIO的服务端编程流程 2. NIO的客户端编程流程 三、相关知识 1. Channel 定义: 主要的实现类: 2. Buffer 3. Selector:选择器 3.1 选择器的使用: 3.2 Seletor选择器中重要类之SelectionKey: 3.3 Selector维护的三种类型SelectionKey集合: 3.4 select()方法介绍: 3.5 selector过程 3.6 停止选择的方法 四、NIO与BIO各自优势 五、BIO、NIO适用场景分析: 六、NIO+多线程编程 AIO BIO Blocking IO: 同步阻塞的编程方式。 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。 且建立好的连接,在通讯过程中,是同步的。在并发处理效率上比较低。大致结构如下: 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理

JAVA IO/NIO

痴心易碎 提交于 2020-02-10 00:50:55
个人博客 http://www.milovetingting.cn JAVA IO/NIO 前言 本文为学习Java相关知识所作笔记,参考以下资料: https://github.com/Snailclimb/JavaGuide ,感谢原作者的分享! JAVA IO/NIO 阻塞 IO 模型 最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除 block 状态。典型的阻塞 IO 模型的例子为:data = socket.read();如果数据没有就绪,就会一直阻塞在 read 方法 非阻塞 IO 模型 当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。所以事实上,在非阻塞 IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞 IO 不会交出 CPU,而会一直占用 CPU。典型的非阻塞 IO 模型一般如下: while

java nio中的字符集

我与影子孤独终老i 提交于 2020-02-09 14:23:53
字符集 一 看支持哪些字符集 //获取字符集 Map<String, Charset> mycharset=Charset.availableCharsets(); Set<Map.Entry<String,Charset>> set=mycharset.entrySet(); for(Map.Entry<String,Charset> entry:set){ System.out.println(entry.getKey()+" = "+entry.getValue()); } 二 编解码 //一个中文俩字节,一个英文一字节 ---编码: 字符串--》字节数组 ---解码:字节数组--》字符串 void test3() throws CharacterCodingException { //获取编码器 //编码器.encode(aCharBuffer);会返回一个ByteBuffer Charset charset=Charset.forName("GBK"); CharsetEncoder encoder=charset.newEncoder(); //获取解码器 //解码器.decode(aByteBuffer);会返回一个CharBuffer Charset charset1=Charset.forName("GBK"); CharsetDecoder decoder

BIO和NIO

删除回忆录丶 提交于 2020-02-09 09:51:33
在了解BIO,NIO,AIO之前先了解一下IO的几个概念: 1.同步与异步 同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) 所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。 而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用(call back)。 2. 阻塞与非阻塞 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态. 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。 BIO是同步阻塞,NIO是同步非阻塞,它们都是同步的,即没有得到结果之前,该*调用*就不返回。而AIO是异步的,这里不做了解。 Java NIO和IO的主要区别 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异。 IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器 面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是

Java IO、BIO、NIO、BIO

大憨熊 提交于 2020-02-09 09:49:27
一、什么是IO/NIO:   IO:即BIO(Blocking IO);面向流的、同步阻塞式IO;(JDK1.4之前唯一的选择)   NIO:面向缓冲的、同步非阻塞式IO;三大核心部分:Selector、Channel(通道)、Buffer(缓冲区);(JDK1.4引进的,一般网络编程中用得较多)   AIO:异步非阻塞式IO;(JDK1.7引进,算较新的特性) 二、同步、异步、阻塞、非阻塞(分布式系统角度理解,较抽象):   同步异步 和 阻塞非阻塞并没有直接的关系。      同异步描述的是一种" 消息机制 ";比如两个线程A,B,线程A请求线程B需要一些数据,然后B去给A拿数据去:(主被动关系)     1:同步机制下,线程A要定时去 主动 的问A数据拿来没有。     2:异步机制下,线程A请求完B,就不管了,B如果把数据拿来准备好了,由 B来通知A 来处理。      阻塞非阻塞:描述的是线程间请求时所处的一种 状态 :(能不能去做别的事)     1:阻塞:体现在A请求B,一直到到读取数据B的过程中,A线程被挂起(期间不能使用CPU),直到当前数据段获取完了。(一次while()的执行)。     2:非阻塞:体现在A请求到获取数据之间,A线程不会被挂起,从 请求 到 准备好数据 这个阶段,A可以离开去做其它事。   注:同步异步,一般我们从编程中的多线程的角度理解是

linux查看进程中线程及线程池

余生长醉 提交于 2020-02-08 20:13:11
1 lsof -i :8084 查看端口程序 2.top -H -p #pid查看相关线程,找出最占资源的线程 3.printf '0x\n' #线程ID(即2中pid)得到线程ID的16进制 4.jstack #pid|grep -A 10 线程ID的16进制 查看进程中所有的线程 jstack #pid|grep nid=0x 查看gc相关的线程号 jstack #pid| grep nid=ox| grep GC | awk '{print "pid=" strtonum("0x"substr($7,7,12))" " $0}' 查看自定义线程池(线程池的名字为xxxTreadPool)相关的线程号 jstack #pid|grep TreadPool- |awk '{print "pid=" strtonum("0x"substr($ 6 ,7,12))" " $0}' 查看http-nio-线程 jstack #pid|grep http-nio- |awk '{print "pid=" strtonum("0x"substr($7,7,12))" " $0}' springboot web程序举例 查看pid top -H -p 122349 ps -T -p 122349 spring boot web程序进程相关线程 jstack 122349|grep nid

Java NIO与Java BIO的区别

梦想与她 提交于 2020-02-08 08:03:42
作者: Monica2333 链接:https://www.jianshu.com/p/8b3af5bf4ce1 来源:简书 1.什么是Java NIO? 同步非阻塞io模式,拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。 Java NIO有三大组成部分:Buffer,Channel,Selector,通过事件驱动模式实现了什么时候有数据可读的问题。 Channel:相当于IO操作的载体,相当于一个硬件设备,一个文件,一个socket或是区别程序中的不同IO操作,如read,write。 channel类似流,但又有些不同: 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。 通道可以异步地读写。 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。 Buffer:用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。 channel 和 buffer 之间的交互如下: Selector:Selector(选择器)是Java NIO中能够检测一到多个NIO通道