了解NIO

【国民技术N32项目移植】基于 Windows 的 ARM GCC 开发环境 阅读详情

NIO与IO的区别

Java NIO(New IO或 Non Blocking IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。

IONIO
面向流编程(Stream Oriented)面向缓冲区编程(Buffer Oriented)
阻塞IO非阻塞IO
无选择器(Seletors)

缓冲区

在Java的NIO中缓冲区是负责数据的存储。其实缓冲区就是一个数组,用于存储不同的类型的数据。根据数据类型的不同,有一下Buffer的常用类:

  • ByteBuffer(常用缓冲区)
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DubleBuffer

    上述缓冲区管理方式几乎一样。都是通过allocate()方法获取缓冲区。
public void test(){
    //声明一个容量为1024大小的字节非直接缓冲区
    ByteBuffer bf = ByteBuffer.allocate(1024);
}

缓冲区中四个核心属性:

  1. capacity: 容量,表示缓冲区中最大存储数据的容量,一旦声明就不能改变。
  2. limit: 界限,表示缓冲区中可以操作数据的大小。(limit之后的数据不能操作)
  3. position: 位置,表示缓冲区中正在操作数据的位置。
  4. mark: 标记,表示记录当前position位置。可以通过reset()方法将position回复到mark位置。

    mark <= position <= limit <= capacity

缓冲区中的常用方法:

  • put()方法存放数据到缓冲区
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		System.out.println(bf.capacity());//容量为1024
		System.out.println(bf.limit());//界限为1024
		System.out.println(bf.position());//当前位置为11
		System.out.println(new String(bf.array()));// Hello world
	}
}
  • flip()将position归零,limit设置为数据的边界处(一般使用该方法进行读写转换)
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip(); //切换为读数据模式
		System.out.println(bf.capacity()); //容量为1024
		System.out.println(bf.limit()); //界限为11
		System.out.println(bf.position()); //当前位置为0
		System.out.println(new String(bf.array())); // hello world
	}
}

注意:

public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip();
		System.out.println(bf.capacity());
		System.out.println(bf.limit());
		System.out.println(bf.position());
		System.out.println(new String(bf.array()));
		System.out.println("-------------");
		bf.put("haha".getBytes());
		System.out.println(bf.capacity());
		System.out.println(bf.limit());
		System.out.println(bf.position());
		System.out.println(new String(bf.array()));
	}
}

输出结果:

1024
11
0
hello world
-------------
1024
11
4
hahao world

从这段代码的运行效果可以看出,在对缓冲区执行了flip()方法后,再对缓冲区执行put()方法,就相当于修改缓冲区的数据,并且position也会发生跟随修改的数据发生变化。注意:修改的数据不能超过limit的限制,如果超出就会抛出:BufferOverflowException异常。该例子充分的证明了,只能操作缓冲区中limit之内的数据,如果操作缓冲区limit之外的数据就会抛出异常。

  • get()读取缓冲区的数据
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip();
		byte[] b = new byte[bf.limit()];
		bf.get(b);
		System.out.println(new String(b));//Hello world
		System.out.println(bf.capacity());// 1024
		System.out.println(bf.limit());// 11
		System.out.println(bf.position());// 11
	}
}
  • rewind()将position归零,取消mark的标记,limit不变(一般采用该方式进行可重复读)
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip();
		byte[] b = new byte[bf.limit()];
		bf.get(b);
		System.out.println(new String(b));
		System.out.println(bf.capacity());
		System.out.println(bf.limit());
		System.out.println(bf.position());
		System.out.println("==========");
		bf.rewind();
		System.out.println(bf.capacity());
		System.out.println(bf.limit());
		System.out.println(bf.position());
	}
}

输出结果:

hello world
1024
11
11
==========
1024
11
0
  • clear()清空缓冲区。但是缓冲区中的数据依然存在,只是出于被遗忘状态
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.clear();
		System.out.println(bf.capacity());//1024
		System.out.println(bf.limit());//1024
		System.out.println(bf.position());//0
		System.out.println((char)bf.get(1));//e
	}
}

实现这种方式,我们不妨使用rewind()方法:

public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.rewind();
		System.out.println(bf.capacity());//1024
		System.out.println(bf.limit());//1024
		System.out.println(bf.position());//0
		System.out.println((char)bf.get(1));//e
	}
}
  • mark()标记此时position的位置,reset()恢复到mark的位置
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip();
		byte[] b = new byte[bf.limit()];
		bf.get(b,0,2);
		System.out.println(bf.position());//2
		System.out.println(new String(b));//he
		bf.mark();
		bf.get(b, 2, 2);
		System.out.println(bf.position());//4
		System.out.println(new String(b));//hell
		bf.reset();
		System.out.println(bf.position());//2
	}
}
  • hasRemaining()判断缓冲区中是否还有剩余的数据,remaining()获取缓冲区剩余数据的数量
public class Test03 {
	public static void main(String[] args) {
		ByteBuffer bf = ByteBuffer.allocate(1024);
		bf.put("hello world".getBytes());
		bf.flip();
		byte[] b = new byte[bf.limit()];
		bf.get(b,0,10);
		if(bf.hasRemaining()) {
			System.out.println(bf.remaining());
		}
		
	}
}
//输出结果为:1

get(int index)、put(int index, byte b)等都不会改变position的值

直接缓冲区和非直接缓冲区:

直接缓冲区:直接在物理内存中创建的缓冲区叫做直接缓冲区。

直接缓冲区

非直接缓冲区:创建的缓存是冲JVM内存中开辟的空间叫做非直接缓冲区。

非直接缓冲区

直接缓冲区一旦创建成功,我们只能控制向缓冲区中读写数据,但是却不能控制缓冲区的数据多久或者何时被操作系统写入到磁盘中。非直接缓冲区的数据写入到磁盘中需要物理内存copy一份JVM虚拟机总的缓存区中的数据,再进行写入磁盘,这种方式相对直接缓冲区再性能和效率上肯定会低很多。

public void test(){
    //创建非直接缓冲区
    ByteBuffer.allocate();
    //创建直接缓冲区
    ByteBuffer.allocateDir();
}

通道

用于源节点与目标节点的连接。在java NIO中负责缓冲区中数据的传输。Channel本身不存储数据,需要配合缓冲区进行传输。通道由java.nio.channels包定义。

通道的主要实现类:

  • java.nio.channels.Channel 接口:
    • FileChannel:用于读取、写入、映射和操作文件的通道。
    • SocketChannel:通过 TCP 读写网络中的数据。
    • ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
    • DatagramChannel:通过 UDP 读写网络中的数据通道。

获取通道主要方式:

  • 1.java针对支持通道的类提供了getChannel()方法

    本地IO:FileInputStream/FileOutputStream、RandomAccessFile

    网络IO:Socket、ServerSocket、DatagramSocket
  • 2.在JDK 1.7 中的NIO.2 针对各个通道提供了静态方法 open()
  • 3.在JDK 1.7 中的NIO.2 的Files工具类的newByteChannel()

例子:使用NIO实现本地磁盘文件的拷贝;

  • 方式1:采用非直接缓冲区
    @Test
	public void test1() throws IOException {
		//获取文件的输入输出流
		FileInputStream in = new FileInputStream("E:/1.pdf");
		FileOutputStream out = new FileOutputStream("E:/2.pdf");
		//获取输入输出管道
		FileChannel outChannel = out.getChannel();
		FileChannel inChannel = in.getChannel();
		//创建一个缓存区
		ByteBuffer bf = ByteBuffer.allocate(1024);
		while((inChannel.read(bf)) != -1) {
			//将缓冲区切换为读取数据模式
			bf.flip();
			outChannel.write(bf);
			//清空缓冲区
			bf.clear();
		}
		//关闭管道和流
		outChannel.close();
		inChannel.close();
		out.close();
		in.close();
	}
  • 方式2:采用直接缓冲区
    @Test
	public void test2() throws IOException {
		// 获取输入输出管道
		FileChannel outChannel = FileChannel.open(Paths.get("E:/2.pdf"), StandardOpenOption.WRITE,
				StandardOpenOption.READ, StandardOpenOption.CREATE);
		FileChannel inChannel = FileChannel.open(Paths.get("E:/1.pdf"), StandardOpenOption.READ);
		//內存映射
		MappedByteBuffer inMapBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outMapBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
		byte[] dst = new byte[inMapBuffer.limit()];
		inMapBuffer.get(dst); //读取数据到数组中
		outMapBuffer.put(dst);
	}
  • 方式3:采用transferTo或者transferFrom方法(该方式也是采用的直接缓冲区)
    @Test
	public void test3() throws IOException {
		//获取输入输出管道
		FileChannel inChannel = FileChannel.open(Paths.get("E:/1.pdf"), StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("2.pdf"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
		//输入管道传输到输出管道
		//inChannel.transferTo(0, inChannel.size(), outChannel);
		outChannel.transferFrom(inChannel, 0, inChannel.size());
	}

NIO的非阻塞式网络编程

传统的 IO 流都是阻塞式的。也就是说,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务。因此,在完成网络通信进行 IO 操作时,由于线程会阻塞,所以服务器端必须为每个客户端都提供一个独立的线程进行处理,当服务器端需要处理大量客户端时,性能急剧下降。

Java NIO 是非阻塞模式的。当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。因此,NIO 可以让服务器端使用一个或有限几个线程来同时处理连接到服务器端的所有客户端。

这种方式就为阻塞式的NIO

public class Test05 {
	@Test
	public void client() throws IOException {
		// 打开客户端链接服务端的通道
		SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8888));
		//指定大小的缓冲区
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byteBuffer.put("hello world".getBytes(Charset.forName("UTF-8")));
		//发送数据
		byteBuffer.flip();
		socketChannel.write(byteBuffer);
		byteBuffer.clear();
		socketChannel.shutdownOutput();//关闭发送通道,表明发送数据完毕
		
		//接受服务端的反馈
		int len = 0;
		while((len = socketChannel.read(byteBuffer)) != -1) {
			byteBuffer.flip();
			System.out.println(new String(byteBuffer.array(),0,len));
			byteBuffer.clear();
		}
		//关闭管道
		socketChannel.close();
	}
	
	@Test
	public void server() throws IOException {
		ServerSocketChannel  ssChannel = ServerSocketChannel.open();
		ssChannel.bind(new InetSocketAddress(8888));
		SocketChannel socketChannel = ssChannel.accept();
		ByteBuffer bf = ByteBuffer.allocate(1024);
		int len = 0;
		while((len= socketChannel.read(bf)) != -1) {
			bf.flip();
			System.out.println(new String(bf.array(),0,len));
			bf.clear();
		}
		//发送反馈信息给客户端
		bf.put("me too".getBytes(Charset.forName("UTF-8")));
		bf.flip();
		System.out.println(new String(bf.array(),0,bf.limit()));
		socketChannel.write(bf);
		ssChannel.close();
		socketChannel.close();
	}
}

选择器Selector

Selector选择器是SelectableChannel对象的多路复用器。Selector 可以同时监控多个 SelectableChannel的IO状况,也就是说,利用 Selector可使一个单独的线程管理多个 Channel。Selector 是非阻塞 IO 的核心。

Selector的常用方法:

方法描述
Set keys()所有的SelectionKey集合,代表注册在Selector上所有的Channel
selectedKey()被选中的SelectionKey的集合,返回Selector已经选中的键表
int select()监控所有注册的Channel,当他们中间有需要处理IO操作时,该方法返回,并将对应得的SelectionKey加入被选中的SelectionKey集合中,该方法返回Channel的数量。
int selectNow()执行一个立即返回的select()方法,该方法不会阻塞线程
Selector wakeup()使得一个还未返回的select()方法立即返回
void close()关闭选择器

SelectionKey

当调用 register(Selector sel, int ops) 将通道注册选择器时,选择器对通道的监听事件,需要通过第二个参数 ops 指定。

监听的事件的类型常量常量值
读SelectionKey.OP_READ1
写SelectionKey.OP_WRITE4
连接SelectionKey.OP_CONNECT8
接收SelectionKey.OP_ACCEPT16

如果注册的时候,不至监听一个事件,可以使用’|'运算符进行多个事件的连接。

SelectionKey的常用方法

方法描述
int interestOps()获取感兴趣的事件集合
int readyOps()获取通道已经准备就绪的操作集合
SelectableChannel channel()获取注册通道
Selector selector()返回选择器
boolean isReadable()检查Channel中读事件是否准备就绪
boolean isWritable()检查Channel中写事件是否准备就绪
boolean isConnectable()检查Channel中连接事件是否准备就绪
boolean isAcceptable()检查Channel中接收事件是否准备就绪

NIO实现非阻塞式的网络编程:

public class Test06 {
	
	@Test
	public void client() throws IOException {
		//创建绑定服务端的管道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9999));
		//切换为非阻塞式模式
		sChannel.configureBlocking(false);
		//分配指定大小的缓冲区
		ByteBuffer bf = ByteBuffer.allocate(1024);
		//发送数据给服务端
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			bf.put(sc.next().getBytes(Charset.forName("UTF-8")));
			bf.flip();
			sChannel.write(bf);
			bf.clear();
		}
		//关不管道
		sChannel.close();
	}
	
	@Test
	public void server() throws IOException {
		//创建服务端管道,并绑定需要监控的端口
		ServerSocketChannel ssChannel = ServerSocketChannel.open();
		ssChannel.bind(new InetSocketAddress(9999));
		ssChannel.configureBlocking(false);
		//获取选择器
		Selector selector = Selector.open();
		//将通道注册到选择器中
		ssChannel.register(selector, SelectionKey.OP_ACCEPT);
		//轮训式获取数据
		while(selector.select()>0) {
			//获取当前选择其中已经被选中的键表
			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			
			while(it.hasNext()) {
				SelectionKey key = it.next();
				//判断事件的类型
				if(key.isAcceptable()) {
					// 若接收就绪,就创建客户端连接的通道
					SocketChannel sChannel = ssChannel.accept();
					// 切换通道为非阻塞式
					sChannel.configureBlocking(false);
					//将通道注册到选择器中
					sChannel.register(selector, SelectionKey.OP_READ);
				}else if(key.isReadable()) {
					//获取当前选择器中"读就绪"的通道
					SocketChannel channel = (SocketChannel) key.channel();
					//读取数据
					ByteBuffer bf = ByteBuffer.allocate(1024);
					int len = 0;
					while((len=channel.read(bf)) > 0) {
						bf.flip();
						System.out.println(new String(bf.array(),0,len,"UTF-8"));
						bf.clear();
					}
				}
				//移除选择键
				it.remove();
			}
			
		}
	}
}

关于UDP、管道等方式,请参考引用部分。

引用:https://blog.youkuaiyun.com/zxm1306192988/article/details/60581173

手把手教你用ComfyUI搭建高效AI绘画工作流:从基础到高级技巧 本文详细介绍了如何使用ComfyUI构建高效的AI绘画工作流,从基础配置到高级技巧全面覆盖。通过模块化设计,ComfyUI显著提升显存利用率和创作灵活性,适合从新手到专业用户。文章包含部署指南、工作流搭建、性能优化及行业应用案例,帮助读者快速掌握AI绘画核心技术。 阅读详情

相关推荐

word 2013 长篇文档排版案例教程

office 2013 制作长文格式模板

1万+

java IO

1 Java中有哪几种类型的流 字符流和字节流,字节流继承inputStream和OutputStream,字符流继承自Reader和Writer, InputStream,OutputStream,Reader,writer都是抽象类。所以不能直接new。 1.1 区别 字节流是最基本的,主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的e...

孟庆云的博客 420

Silvaco TCAD仿真例库——肖特基二极管正向特性(例子)

此示例演示了肖特基二极管正向特性的仿真。 展示了: 使用 Atlas 语法形成二极管结构 设置阳极的肖特基势垒高度 正向偏置阳极 代码 第一部分:描述设备 mesh(网格) electrodes locations(电极位置) doping distribution(掺杂分布) 这是位于结构左侧和右侧的,2维n型器件,具有重掺杂浮动 p 型保护环区域, (2D n-type device with heavily doped floating p-type guard ring regio.

weixin_41788560的博客 2万+

Java NIO 系列教程(二)

直接缓冲区与非直接缓冲区 非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在Jvm内存中。 可以观察到非直接缓冲区需要在内核地址空间(OS)和用户地址空间之间(JVM)之间进行数据复制的操作,将缓冲区建立在物理内存中的可以免除中间的复制操作,提高效率因此产生了直接缓冲区。 直接缓冲区:通过allocateDirect()工厂方法来创建。此方法的缓冲区进行分配和取消分配所需的成本通常

Nobigo 635

浮点数运算的陷阱与启示:FP16加法器/乘法器开发中的常见误区

本文深入探讨FP16加法器和乘法器开发中的常见误区,包括FP16格式解析、阶码对齐陷阱、尾数运算风险及规格化处理。通过Verilog实战代码展示防御性编程技巧,帮助开发者避免边界条件处理和异常状态管理中的错误,提升硬件设计的可靠性和效率。

dell8的博客 250

Arduino程序设计(八)LCD显示实验

本文主要介绍温度/温湿度传感器的LCD显示实验,分别是:1、LM35采集环境温度LCD显示;2、DS18B20采集环境温度LCD显示;3、DHT11采集环境温湿度LCD显示。(1)LM35介绍LM35特性特性说明基本功能LM35作为常用的温度传感器,可以检测周围的温度工作原理利用感温材料,通过内部电路将温度值转化为对应的电压信号工作电压4~30V,常用5V供电温度测量测量范围0~100℃ ,误差 ±0.5℃输出信号线性模拟信号输出,LM35输出电压和摄氏温度程线性关系。

Alice的博客 6711

NIO:缓冲区(Buffer);通道(Channel);Files 类常用方法;Path 与 Paths

文章目录NIO一、缓冲区(Buffer)1、Buffer概述2、缓冲区基本属性3、缓冲区常用方法4、演示二、通道(Channel)1、Channel概述2、获取通道方式一:使用支持通道的类的对象调用getChannel() 方法方式二:使用 Files 类的静态方法newByteChannel() 获取字节通道方式三:通道的静态方法 open() 打开并返回指定通道3、通道的数据传输4、NIO...

y_Engineer的博客 1174

LatentSync:开源数字人唇形同步技术的实战部署与优化指南

本文详细介绍了开源数字人唇形同步工具LatentSync的实战部署与优化全流程。从核心原理(潜在扩散模型与TREPA技术)解析,到手把手完成环境搭建、模型获取及首次推理。文章深入探讨了自定义素材处理、关键参数调优(如guidance_scale),并提供了显存不足、人脸检测失败等常见问题的解决方案与性能优化技巧,旨在帮助用户高效部署并提升生成效果。

9o8p7i6u5y的博客 1008

NIO中channel的使用(包括直接缓冲区和非直接缓冲区)

一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。     二、通道的主要实现类    java.nio.channels.Channel 接口:   |--FileChannel    |--SocketChannel    |--ServerSocketChannel

qq_33804730的博客 1560

15、SQL Server查询优化与CPU负载管理

本文深入探讨了SQL Server查询优化与CPU负载管理的关键技术,包括强制连接类型的使用、键查找问题的解决、索引设计的最佳实践、高CPU负载的排查与优化,以及并行性的利弊与调整策略。通过优化查询逻辑、合理设计索引、监控与管理CPU资源,可以显著提升SQL Server的性能和稳定性。适用于数据库开发人员和DBA进行性能调优参考。

pz8901234的博客 78

《二、企业级监控系统之Prometheus监控node_exporter》

文章目录一、部署node_exporter服务二、部署prometheus服务2.1、部署node_exporter服务三、grafana之添加数据源四、grafana之导入监控模板五、grafana之修改模板变量六、grafana之修改仪表板变量总结 > 这里是引用 一、部署node_exporter服务 docker run -d --restart=always --name node_exporter --net=“host” --pid=“host” -v “/:/host:ro,

东城绝神 1万+

NIO 工作原理

NIO 工作原理

weixin_46619605的博客 1634

RK356X linux系统移植RTL8723BU模块遇到的坑

RK356X linux系统移植RTL8723BU模块遇到的坑

目前从事linux驱动开发,多交流多学习吧 954

了解NIO的概述

同步与异步(synchronous/asynchronous) 同步: 调用方法之后,必须要得到一个返回值 异步: 调用方法之后,没有返回值,但是会有回调函数,回调函数指的是满足条件之后会自动执行的方法 阻塞与非阻塞 阻塞:如果没有达到方法的目的,就会一直停在那里(等待) , 例如: ServerSocket的accept()方法 非阻塞: 不管方法有没有达到目的,都直接往下执行(不等待) NIO 这是一个面向块的I/O系统,系统以块的方式处理数据 NIO之所以是同步,是因为它的accept/r

weixin_53589418的博客 232

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NIO的总结,NIO与IO的区别,NIO的优势,带你了解NIO

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma...

u011770875的博客 2763

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

NIO你真正了解多少?

新人大礼包,30G Java架构资料,免费领取 解释一下java.io.Serializable接口 类通过实现 Java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。 IO操作最佳实践 使用有缓冲的IO类,不要单独读取字节或字符 使用NIO和NIO 2或者AI...

不喝枸杞的程序员 252

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

深入了解NIO底层原理

Redis 为何能支持高并发? Redis底层采用NIO中的多路IO复用的机制,很好地支持高并发,并且能实现线程安全。 Redis官方没有windows版本,只有Linux版本。 NIO在不同的操作系统上实现的方式有所不同,在Windows操作系统使用select实现轮训,而且还存在空轮训的情况,效率非常低。时间复杂度是为O(n)。其次默认对轮训的数据有一定限制,所以难于支持上万的TCP连接。 在Linux操作系统采用epoll实现事件驱动回调,不会存在空轮训的情况,只对活跃的socket连接实现主动回调,

陈皮的JavaLib 2658

二、深入了解NIO

深入了解NIO 同步异步:消息的通信方式是同步的还是异步的 阻塞非阻塞:调用者在拿得到被调用者返回结果之前的状态 NIO 从JDK1.4 提出的,本意是New IO(相对于传统IO),它的出现为了弥补IO的不足, 提供了更高效的方式,提高服务端处理的性能。 NIO(相同点:数据源) 不同点(通信方式不一样) 本地磁盘 网络(Select/poll)多路复用,提升服务端处理连接数量(不会阻塞)。 NIO的新特性: NIO的所有操作一定是基于缓冲区的(面向缓冲区) 通道(Channel):

u010868192的博客 690

NIO的了解

1、流一旦打开,就必须关闭,使用close方法, 放入finally语句块中(finally语句块一定会执行) 多个流互相调用,只关闭最外层的流。 2、InputStreamReader的reader方法,返回所读取的字节的int类型(0-255), read(byte[] data)将读取的字节,存储在这个数组里,返回传入数组参数个数 3、write(byte b[], int off, int len) 将指定字节传入数据源,off是第一个字节的位置,len是长度 4、JAVA序列...

我3的博客 221

NIO学记:一、了解NIO

1. Java NIO全称java non-blocking IO, 是指JDK提供的新API。从JDK1.4开始,Java提供了一系列改进的输入/输出的新特性,被统称为NIO(即New IO),是同步非阻塞的 2. NIO有三大核心部分: Channel(通道), Buffer(缓冲区),Selector(选择器) 3. NIO是面向缓冲区,或者面向块编程的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络。......

weixin_39327352的博客 272

Nio 初步了解

1.对于基本的javaSE我们更多的了解是jdk的api提供给我们的IO包的使用,比如说构建抽象路径的File   基本的字节流,字符流  转换流的使用。但是基于jdk 1.4版本和现在1.7版本提供给我们的NIO包下的流很少有人知道和使用,因为我们习惯的使用了IO包下的流,最近做一个调度系统其中包括文件的传输,基于协议传输希望采用netty来实现,但是实际上netty是基于NIO来实现的,所以我...

灰色的小熊的博客 395

NIO的浅了解

用户进程一直等待数据准备好,在复制完成之前都是阻塞的。

瞅你咋滴。 717

Java NIO 简单了解

Java NIO 简单了解一直没有了解过NIO,更没有用过NIO,由于很多分布式框架或多或少都涉及到了NIO,因此,先做个简单了解。NIO入门推荐:NIO 入门,入门教程中没有比这篇更合适的了。NIO文件读取和写入一个简单的文件复制例子。首先创建两个输入输出流:FileInputStream fin = new FileInputStream("D:/test.txt"); FileOutputSt

偶尔记一下 - mybatis.io 2143

什么是NIO?快速了解IO和NIO底层原理

目录 一、首先,我们来了解一下Java IO的读写原理: 1.1、内核缓冲与进程缓冲区 1.2、java IO读写的底层流程 二、四种主要的IO模型 1.3. 同步阻塞IO(Blocking IO) 1.4. 同步非阻塞NIO(None Blocking IO) 1.5. IO多路复用模型(I/O multiplexing) 1.6. 异步IO模型(asynchronous IO) 总结: 一、首先,我们来了解一下Java IO的读写原理: 简介:IO是Input和Output的缩写.

欢迎来到 程序猿 的博客 3706

了解NIO原理机制

个人博客请访问http://www.x0100.top NIO和IO到底有什么区别?有什么关系? 首先说一下核心区别: NIO是以块的方式处理数据,但是IO是以最基础的字节流的形式去写入和读出的。所以在效率上的话,肯定是NIO效率比IO效率会高出很多。 NIO不在是和IO一样用OutputStream和InputStream 输入流的形式来进行处理数据的,但是又是基于这种流的形式,而是采用了通道和缓冲区的形式来进行处理数据的。 还有一点就是NIO的通道是...

HelloWorld搬运工 452

NIO的初识与了解

IO IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 1.什么是BIO BIO(同步阻塞):每一个IO请求都会有一个线程去处理,如果数据没有准备就绪,线程会一直等待。直到数据读取完毕线程才会释放,在此期间,进程不回去做任何其他任务,这种模式会浪费一定的线程资源。 2.什么是NIO NIO(同步非阻塞):NIO的优点在于首先基于缓存读写文件,能够批量操作,然后用channel双向读写数据,减少每次打开断开流的资源消耗。引入selecore的概念,用一个线程管理多个通道,大

m0_46684016的博客 322
上一篇: SpringCloud之Ribbon
下一篇: SpringMVC对validation的支持
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值