一,先说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);
}
}

运行结果:

最新文章

  1. 要当好JavaScript程序员:5个debug技巧
  2. DNS记录类型介绍(A记录、MX记录、NS记录等)
  3. with(nolock)的用法
  4. @ResultMapping注解
  5. HDU 2042 不容易系列之二 [补6.24] 分类: ACM 2015-06-26 20:40 9人阅读 评论(0) 收藏
  6. 【转】iOS学习之Autolayout(代码添加约束) -- 不错不错
  7. java数据结构之hash表
  8. List(列表)
  9. Android MVP模式 简单易懂的介绍方式
  10. GetRect:通过提供点和宽度返回对应矩形RECT
  11. EF4.1: Add/Attach and Entity States(EF中的实体状态转换说明)
  12. SecuerCRT遇到一个致命错误且必须关闭_解决方案_软件链接(自己百度云盘的)
  13. POJ 1321 棋盘问题(搜索的方式)
  14. 983. Minimum Cost For Tickets
  15. C++学习笔记(一):C++基础知识
  16. 举例跟踪linux内核系统调用
  17. C# ADO.NET中设置Like模糊查询的参数
  18. collections和collection 还有集合
  19. 25个常用PowerShell命令总结
  20. CSS3 2D转换 动画

热门文章

  1. Vue19 常用指令及自定义指令
  2. Vue视频 | 【Vue2 + Vue3 前端教程】完整版
  3. voxel体素网络滤波器
  4. 微信小程序-【转发好友】以及中文标题乱码问题解决
  5. C语言补漏--内存管理-完结
  6. 安卓逆向 JNI实先java与C互通
  7. TCP/IP协议(5): IP(Internet Protocol) 协议 —— 连接各个网络的协议
  8. TCP/IP协议(3): Wi-Fi(IEEE 802.11) 协议 —— 构成无线局域网的基本协议
  9. 如何在Net6.0里配置多版本支持并支持注释说明的Swagger
  10. 【NOIP2017提高组正式赛】列队