java NIO原理和代码实践
一,先说java IO
1,线程阻塞:当线程调用write()
或read()
时,线程会被阻塞,直到有一些数据可用于读取或数据被完全写入。
2,面向流: 我们需要从流中读取一个或多个字节。它使用流来在数据源/槽和java程序之间传输数据。从源进入 Java对象成为“input” , 从Java 对象 写出称为“ouput” .
二,同步非阻塞IO:当内核数据没有准备好的情况下,并不会一直阻塞等待,而是立即返回。随后多次发起系统调用,轮询过程。
优点: 不会等待阻塞,失败立即返回。
缺点: 多次发起调用,轮询过程消耗资源。
三,多路复用IO:select/epoll系统调用,单个线程不断的轮询select/epoll系统调用所负责的成百上千的socket连接,当某个或者某些socket网络连接有数据到达了,就返回这些可 以读写的连接。 在 Linux 下,实现高并发网络编程时都是以 IO 复用模型模式为主。这是同步非阻塞的升级。
优点:之前是一个线程对应一个连接。现在是一个线程对应多个连接。 适合高并发场景;系统不必创建线程,也不必维护这些线程,从而大大减小了系统的开销。
缺点:需要不断的进行select/epoll轮询,查找出可以进行IO操作的连接;select/epoll系统调用,属于同步IO,也是阻塞IO。也就是说这个读写过程是阻塞的。
二,java NIO 原理
就是多路复用原理。
三 , NIO 简单例子
package org.example; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set; public class NIOServer { public static void main(String[] args) throws IOException { Selector selector = Selector.open(); // 开启选择器
ServerSocketChannel SocketChannel = ServerSocketChannel.open();
InetSocketAddress addr = new InetSocketAddress("localhost", 1111);
SocketChannel.bind(addr); //服务器端建立channel ,绑定到端口
SocketChannel.configureBlocking(false); // 配置channel阻塞模式
int ops = SocketChannel.validOps();
SelectionKey selectKy = SocketChannel.register(selector, ops, null);
// 无限循环,保持服务器运行
while (true) {
log("我是服务器,我在等待连接... ");
selector.select(); // 从很多key中选择 已IO准备好的channel
Set<SelectionKey> Keys = selector.selectedKeys(); //从选择器中选择“已准备好的通道(对应的key)”
Iterator<SelectionKey> Iterator = Keys.iterator();
while (Iterator.hasNext()) {
SelectionKey myKey = Iterator.next();
//测试通道是否可以接收socket 连接
if (myKey.isAcceptable()) {
SocketChannel socketChannel = SocketChannel.accept();
// 修改通道阻塞模式
socketChannel.configureBlocking(false);
// 为读操作进行配置
socketChannel.register(selector, SelectionKey.OP_READ);
log("成功连接到: " + socketChannel.getLocalAddress() + "\n");
// 测试通道是否可以读
} else if (myKey.isReadable()) {
SocketChannel socketChannel = (SocketChannel) myKey.channel();
ByteBuffer Buffer = ByteBuffer.allocate(256);
socketChannel.read(Buffer);
String result = new String(Buffer.array()).trim();
log("接收到消息: " + result);
if (result.equals(".com")) {
socketChannel.close();
log("\n接收到最后一个companie name,可以关闭连接 ''");
log("\n服务器保持运行,可以继续重启客户端建立新连接进行测试。 ");
}
}
Iterator.remove();
}
}
} private static void log(String str) {
System.out.println(str);
}
} public class NIOClient {
public static void main(String[] args) throws IOException, InterruptedException { InetSocketAddress addr = new InetSocketAddress("localhost", 1111); // 建立数据报通道,并绑定地址
SocketChannel socketChannel = SocketChannel.open(addr); //channel 绑定到端口。 log("连接到服务器,端口1111...");
ArrayList<String> companyDetails = new ArrayList<String>(); //构造传输的数据 companyDetails.add("Facebook");
companyDetails.add("Twitter");
companyDetails.add("IBM");
companyDetails.add("Google");
companyDetails.add("alibaba.com");
companyDetails.add(".com"); for (String companyName : companyDetails) {
byte[] message = new String(companyName).getBytes();
ByteBuffer buffer = ByteBuffer.wrap(message); // 功能:定位 ,容量,
socketChannel.write(buffer); //将Buffer中的数据读入通道
log("发送消息: " + companyName);
buffer.clear();
Thread.sleep(2000);
}
socketChannel.close();
} private static void log(String str) {
System.out.println(str);
}
}
运行结果:
java NIO原理和代码实践的更多相关文章
- [JavaEE]Java NIO原理图文分析及代码实现
转http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别 1. 阻塞I/O通信模型 2. java NIO ...
- Java NIO原理图文分析及代码实现
原文: http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别 1. 阻塞I/O通信模型 2. java ...
- Java NIO原理 图文分析及代码实现
Java NIO原理图文分析及代码实现 前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请 ...
- Java NIO原理分析
Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构.一种简单而又直接的解决方案是“one-th ...
- Java NIO原理和使用
Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内 ...
- Java NIO原理和使用(转载一)
Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内 ...
- Java NIO原理及实例
Java NIO是在jdk1.4开始使用的,它既可以说成“新I/O”,也可以说成非阻塞式I/O.下面是java NIO的工作原理: 1. 由一个专门的线程来处理所有的 IO 事件,并负责分发. 2. ...
- java NIO 原理解析之学习笔记
关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...
- 10分钟看懂, Java NIO 底层原理
目录 写在前面 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步阻塞IO(Blocking ...
- java NIO系列教程1
ava NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式. Java NIO: Channel ...
随机推荐
- git分支的一些处理情况记录
一.开发分支(dev)上的代码更新后,要合并到 master 分支 git checkout dev #切换到dev分支 git pull #将远程更新的代码同步到本地 git checkout ma ...
- 不像JVM的JVM
1.面向对象 面向对象的思想:将功能封装到对象中,通过对象去实现 面向对象的目的:将复杂的事情简单化,将以前过程中的执行者变成了指挥者且符合现在人们的思考习惯 面向对象的三大特征: 封装:将对象的实现 ...
- LC761.特殊的二进制序列
import org.junit.jupiter.api.Test;import java.util.ArrayList;import java.util.Collections;import jav ...
- [IOI2013]robots 机器人
题目传送门 思路 简单题,设函数 \(f_i\) 表示当时间为 \(i\) 时是否能够收拾好所有玩具,则 \(f_i\) 显然是单调的. 所以我们可以考虑二分. 设我们当前二分到 \(x\),我们先把 ...
- https://lamp.sh/
转载:LAMP一键安装包 LAMP一键安装包
- PostgreSQL处理膨胀与事务回卷
一.表膨胀查询与处理 1.创建扩展 create extension pgstattuple; 2.表膨胀查询 pgstattuple提供了pgstatetuple()和pgstatindex()两个 ...
- Java第四讲动手动脑
1. 在以上的代码中,main方法调用的是public void println(Object x),这一方法调用了String类的valueOf方法,valueOf方法内部调用Object. toS ...
- 微信轰炸Python脚本
1 import time 2 3 from pynput.keyboard import Key,Controller 4 5 keyboard = Controller() 6 7 a = inp ...
- channel 死锁
死锁: - 单个协程永久阻塞 - 两个或两个以上的协程执行过程中,由于竞争资源或由于彼此通信而造成的一种阻塞的现象. channel 死锁场景: - 非缓存channel只写不读 - 非缓存chann ...
- css 属性选择器需要加引号吗
平常我们是不加引号的: HTML: <div data-a='aq1'>99</div> CSS: [data-a=aq1]{ color: #f00; } 想加上也行 ...