当前位置: 首页 > news >正文

智慧团建官网登录百度关键词优化的意思

智慧团建官网登录,百度关键词优化的意思,许昌 网站建设,互联网营销缺点1. NIO简介 在开始前#xff0c;让我们再简单回顾一下NIO。 在传统的 Java I/O 模型#xff08;BIO#xff09;中#xff0c;I/O 操作是以阻塞的方式进行的。也就是说#xff0c;当一个线程执行一个 I/O 操作时#xff0c;它会被阻塞直到操作完成。这种阻塞模型在处理多…1. NIO简介 在开始前让我们再简单回顾一下NIO。 在传统的 Java I/O 模型BIO中I/O 操作是以阻塞的方式进行的。也就是说当一个线程执行一个 I/O 操作时它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈因为需要为每个连接创建一个线程而线程的创建和切换都是有开销的。 为了解决这个问题在 Java1.4 版本引入了一种新的 I/O 模型 — NIO New IO也称为 Non-blocking IO 。NIO 弥补了同步阻塞 I/O 的不足它在标准 Java 代码中提供了非阻塞、面向缓冲、基于通道的 I/O可以使用少量的线程来处理多个连接大大提高了 I/O 效率和并发。 ⚠️需要注意使用 NIO 并不一定意味着高性能它的性能优势主要体现在高并发和高延迟的网络环境下。当连接数较少、并发程度较低或者网络传输速度较快时NIO 的性能并不一定优于传统的 BIO 。 2. NIO核心组件 NIO 主要包括以下三个核心组件 Buffer缓冲区NIO 读写数据都是通过缓冲区进行操作的。读操作的时候将 Channel 中的数据填充到 Buffer 中而写操作时将 Buffer 中的数据写入到 Channel 中。Channel通道Channel 是一个双向的、可读可写的数据传输通道NIO 通过 Channel 来实现数据的输入输出。通道是一个抽象的概念它可以代表文件、套接字或者其他数据源之间的连接。Selector选择器允许一个线程处理多个 Channel基于事件驱动的 I/O 多路复用模型。所有的 Channel 都可以注册到 Selector 上由 Selector 来分配线程来处理事件。 三者的关系 我们都知道BIO是以流的方式来处理数据的而NIO是以Buffer缓冲器和Channel通道配合来处理数据的。简单来说就是不妨把buffer类比为火车那么channel就是铁路NIO就是通过channel通道运输着存储数据的buffer来实现数据处理。buffer和channel各司其职channel不与数据打交道只负责运输。 BIO中流的单向的。但是对于NIO基于channel的概念我们的读写都是双向的。 下面我们一个一个来看NIO的组件。 3. 缓冲区Buffer Buffer是缓冲器的抽象类 Buffer的实现类中我们用的最多的就是ByteBuffer了它可以用来存储和操作字节数据。 作为一个缓冲区最重要的功能就是写数据进去和从里面拿数据也就是put方法和get方法。在具体看之前我们先看一下Buffer类中定义的四个成员变量具体含义见注释 // 大小关系: 0 mark position limit capacity// Buffer允许将位置直接定位到该标记处这是一个可选属性 private int mark -1; // 下一个可以被读写的数据的位置索引。 // 从写操作模式到读操作模式切换的时候(flip)position归零这样就可以从头读写 private int position 0; // Buffer 中可以读/写数据的边界。 // 写模式下limit代表最多能写入的数据一般等于capacity(可以通过limit(int newLimit)方法设置) // 读模式下limit 等于Buffer中实际写入的数据大小。 private int limit; // Buffer可以存储的最大数据量Buffer创建时设置且不可改变. private int capacity;Buffer 有读模式和写模式这两种模式分别用于从Buffer中读取数据或者向Buffer中写入数据。Buffer被创建之后默认是写模式调用flip()可以切换到读模式。如果要再次切换回写模式可以调用clear()或者compact()方法。 Buffer 对象不能通过 new 调用构造方法创建对象 只能通过静态方法实例化 Buffer。 这里以 ByteBuffer为例进行介绍 // 分配堆内存 public static ByteBuffer allocate(int capacity); // 分配直接内存 public static ByteBuffer allocateDirect(int capacity);Buffer 最核心的两个方法 get: 读取缓冲区的数据put向缓冲区写入数据 除上述两个方法之外其他的重要方法 flip将缓冲区从写模式切换到读模式它会将 limit 的值设置为当前 position 的值将 position 的值设置为 0。clear: 清空缓冲区将缓冲区从读模式切换到写模式并将 position 的值设置为 0将 limit 的值设置为 capacity 的值。… 来看个实战 import java.nio.*;public class CharBufferDemo {public static void main(String[] args) {// 分配一个容量为8的CharBufferCharBuffer buffer CharBuffer.allocate(8);System.out.println(初始状态);printState(buffer);// 向buffer写入3个字符buffer.put(a).put(b).put(c);System.out.println(写入3个字符后的状态);printState(buffer);// 调用flip()方法准备读取buffer中的数据将 position 置 0,limit 的置 3buffer.flip();System.out.println(调用flip()方法后的状态);printState(buffer);// 读取字符while (buffer.hasRemaining()) {System.out.print(buffer.get());}// 调用clear()方法清空缓冲区将 position 的值置为 0将 limit 的值置为 capacity 的值buffer.clear();System.out.println(调用clear()方法后的状态);printState(buffer);}// 打印buffer的capacity、limit、position、mark的位置private static void printState(CharBuffer buffer) {System.out.print(capacity: buffer.capacity());System.out.print(, limit: buffer.limit());System.out.print(, position: buffer.position());System.out.print(, mark 开始读取的字符: buffer.mark());System.out.println(\n);} }--------------------------------------------------------------- output 初始状态 capacity: 8, limit: 8, position: 0写入3个字符后的状态 capacity: 8, limit: 8, position: 3准备读取buffer中的数据调用flip()方法后的状态 capacity: 8, limit: 3, position: 0读取到的数据abc调用clear()方法后的状态 capacity: 8, limit: 8, position: 0画个图方便大家理解 4. 通道Channel Channel 通道只负责传输数据、不直接操作数据。操作数据都是通过 Buffer 缓冲区来进行操作通常通道可以分为两大类文件通道和套接字通道。 FileChannel用于文件 I/O 的通道支持文件的读、写和追加操作。FileChannel 允许在文件的任意位置进行数据传输支持文件锁定以及内存映射文件等高级功能。FileChannel 无法设置为非阻塞模式因此它只适用于阻塞式文件操作。SocketChannel用于 TCP 套接字 I/O 的通道。SocketChannel 支持非阻塞模式可以与 Selector下文会讲一起使用实现高效的网络通信。SocketChannel 允许连接到远程主机进行数据传输。ServerSocketChannel用于监听 TCP 套接字连接的通道。与 SocketChannel 类似ServerSocketChannel 也支持非阻塞模式并可以与 Selector 一起使用。ServerSocketChannel 负责监听新的连接请求接收到连接请求后可以创建一个新的 SocketChannel 以处理数据传输。DatagramChannel用于 UDP 套接字 I/O 的通道。DatagramChannel 支持非阻塞模式可以发送和接收数据报包适用于无连接的、不可靠的网络通信。 因为 Channel 是全双工的所以它可以比流更好地映射底层操作系统的 API。特别是在 UNIX 网络编程模型中底层操作系统的通道都是全双工的同时支持读写操作。 Channel 最核心的两个方法 read 读取数据并写入到 Buffer 中。write 将 Buffer 中的数据写入到 Channel 中。 这里我们以 FileChannel 为例演示一下如何复制文件 Test public void test007() throws IOException{FileChannel readChannel FileChannel.open(Paths.get(test.txt),StandardOpenOption.READ);FileChannel writeChannel FileChannel.open(Paths.get(test_nio.txt),StandardOpenOption.WRITE,StandardOpenOption.CREATE);ByteBuffer buffer ByteBuffer.allocate(1024);while(readChannel.read(buffer)!-1){buffer.flip();writeChannel.write(buffer);buffer.clear();}readChannel.close();writeChannel.close(); }5. 选择器Selector Selector选择器是 NIO 中的一个关键组件它允许一个线程处理多个 Channel。Selector 是基于事件驱动的 I/O 多路复用模型主要运作原理是通过 Selector 注册通道的事件Selector 会不断地轮询注册在其上的 Channel。当事件发生时比如某个 Channel 上面有新的 TCP 连接接入、读和写事件这个 Channel 就处于就绪状态会被 Selector 轮询出来。Selector 会将相关的 Channel 加入到就绪集合中。通过 SelectionKey 可以获取就绪 Channel 的集合然后对这些就绪的 Channel 进行相应的 I/O 操作。 一个多路复用器 Selector 可以同时轮询多个 Channel由于 JDK 使用了epoll()代替传统的 select 实现所以它并没有最大连接句柄 1024/2048 的限制。这也就意味着只需要一个线程负责 Selector 的轮询就可以接入成千上万的客户端。 Selector 可以监听以下四种事件类型 SelectionKey.OP_ACCEPT表示通道接受连接的事件这通常用于 ServerSocketChannelSelectionKey.OP_CONNECT表示通道完成连接的事件这通常用于 SocketChannelSelectionKey.OP_READ表示通道准备好进行读取的事件即有数据可读SelectionKey.OP_WRITE表示通道准备好进行写入的事件即可以写入数据。 Selector是抽象类可以通过调用此类的open()静态方法来创建Selector实例。Selector可以同时监控多个SelectableChannel的 IO 状况是非阻塞 IO 的核心。 一个Selector实例有三个SelectionKey集合 所有的SelectionKey集合代表了注册在该Selector上的Channel这个集合可以通过keys()方法返回。被选择的SelectionKey集合代表了所有可通过select()方法获取的、需要进行 IO 处理的 Channel这个集合可以通过selectedKeys()返回。被取消的SelectionKey集合代表了所有被取消注册关系的Channel在下一次执行select()方法时这些 Channel 对应的 SelectionKey 会被彻底删除程序通常无须直接访问该集合也没有暴露访问的方法。 简单看一下如何遍历被选择的SelectionKey集合并进行处理 SetSelectionKey selectedKeys selector.selectedKeys(); IteratorSelectionKey keyIterator selectedKeys.iterator(); while (keyIterator.hasNext()) {SelectionKey key keyIterator.next();if (key ! null) {if (key.isAcceptable()) {// ServerSocketChannel 接收了一个新连接} else if (key.isConnectable()) {// 表示一个新连接建立} else if (key.isReadable()) {// Channel 有准备好的数据可以读取} else if (key.isWritable()) {// Channel 有空闲的 Buffer可以写入数据}}keyIterator.remove(); }Selector 还提供了一系列和select()相关的方法 int select()监控所有注册的 Channel当它们中间有需要处理的 IO 操作时该方法返回并将对应的 SelectionKey 加入被选择的 SelectionKey 集合中该方法返回这些 Channel 的数量。int select(long timeout)可以设置超时时长的 select() 操作。int selectNow()执行一个立即返回的 select() 操作相对于无参数的 select() 方法而言该方法不会阻塞线程。Selector wakeup()使一个还未返回的 select() 方法立刻返回。…… 来看一个使用Selector实现网络读写的简单demo 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 NioSelectorExample {public static void main(String[] args) {try {ServerSocketChannel serverSocketChannel ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);serverSocketChannel.socket().bind(new InetSocketAddress(8080));Selector selector Selector.open();// 将 ServerSocketChannel 注册到 Selector 并监听 OP_ACCEPT 事件serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {int readyChannels selector.select();if (readyChannels 0) {continue;}SetSelectionKey selectedKeys selector.selectedKeys();IteratorSelectionKey keyIterator selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key keyIterator.next();if (key.isAcceptable()) {// 处理连接事件ServerSocketChannel server (ServerSocketChannel) key.channel();SocketChannel client server.accept();client.configureBlocking(false);// 将客户端通道注册到 Selector 并监听 OP_READ 事件client.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {// 处理读事件SocketChannel client (SocketChannel) key.channel();ByteBuffer buffer ByteBuffer.allocate(1024);int bytesRead client.read(buffer);if (bytesRead 0) {buffer.flip();System.out.println(收到数据 new String(buffer.array(), 0, bytesRead));// 将客户端通道注册到 Selector 并监听 OP_WRITE 事件client.register(selector, SelectionKey.OP_WRITE);} else if (bytesRead 0) {// 客户端断开连接client.close();}} else if (key.isWritable()) {// 处理写事件SocketChannel client (SocketChannel) key.channel();ByteBuffer buffer ByteBuffer.wrap(Hello, Client!.getBytes());client.write(buffer);// 将客户端通道注册到 Selector 并监听 OP_READ 事件client.register(selector, SelectionKey.OP_READ);}keyIterator.remove();}}} catch (IOException e) {e.printStackTrace();}} }在示例中我们创建了一个简单的服务器监听 8080 端口使用 Selector 处理连接、读取和写入事件。当接收到客户端的数据时服务器将读取数据并将其打印到控制台然后向客户端回复 “Hello, Client!”。 6. NIO零拷贝 零拷贝是提升 IO 操作性能的一个常用手段像 ActiveMQ、Kafka 、RocketMQ等消息队列都用到了零拷贝。 零拷贝Zero-Copy是一种优化数据传输性能的技术它最大限度地减少了在数据传输过程中的 CPU 和内存开销。在传统的数据传输过程中数据通常需要在用户空间和内核空间之间进行多次拷贝这会导致额外的 CPU 和内存开销。零拷贝技术通过避免这些多余的拷贝操作实现了更高效的数据传输。 下图为零拷贝技术对比图 CPU拷贝DMA拷贝系统调用上下文切换传统方法22readwrite4mmapwrite12mmapwrite4sendfile12sendfile2sendfileDMA gather copy02sendfile2 可以看出无论是传统的 I/O 方式还是引入了零拷贝之后2 次 DMA(Direct Memory Access) 拷贝是都少不了的。因为两次 DMA 都是依赖硬件完成的。零拷贝主要是减少了 CPU 拷贝及上下文的切换。 Java对零拷贝的支持 MappedByteBuffer是 NIO 基于内存映射mmap这种零拷贝方式的提供的⼀种实现底层实际是调用了 Linux 内核的 mmap 系统调用。它可以将一个文件或者文件的一部分映射到内存中形成一个虚拟内存文件这样就可以直接操作内存中的数据而不需要通过系统调用来读写文件。FileChannel的transferTo()/transferFrom()是 NIO 基于发送文件sendfile这种零拷贝方式的提供的一种实现底层实际是调用了 Linux 内核的 sendfile系统调用。它可以直接将文件数据从磁盘发送到网络而不需要经过用户空间的缓冲区。 7. 总结 这篇文章我们主要介绍了 NIO 的核心知识点包括 NIO 的核心组件和零拷贝。如果我们需要使用 NIO 构建网络程序的话不建议直接使用原生 NIO编程复杂且功能性太弱推荐使用一些成熟的基于 NIO 的网络编程框架比如 Netty。Netty 在 NIO 的基础上进行了一些优化和扩展比如支持多种协议、支持 SSL/TLS 等等。
http://www.pierceye.com/news/282256/

相关文章:

  • 如何能把网站做的更大赤峰网站建设赤峰
  • 织梦大气绿色大气农业能源化工机械产品企业网站源码模版网站设计是用ps做图吗
  • 长沙建设网站公司浙江网站建设上市公司
  • 成都艾邦视觉专业网站建设公司有内涵大气的公司名字
  • 制作学校网站编程基础知识大全
  • 建设银行网站买手机阿里云已备案域名购买
  • 12个优秀的平面设计素材网站wordpress 标题 拼音
  • 瑶海区网站建设公司上海app开发定制公司
  • 北海建设厅网站局域网的电脑怎么做网站服务器
  • 莱芜网站建设价格域名注册成功后怎么使用网站
  • 衡阳县建设局网站wordpress 图片缓存
  • 浙江门户网站建设公司新闻稿发布
  • 温州网站建设排名wordpress 汉化失败
  • 做数据可视化的网站推广类软文案例
  • 外包做网站的要求怎么写做网站 360
  • 温州网站建设价格技术微信公众号免费开通
  • 做网站推广销售怎么样辽宁省网站备案系统
  • html公司网站模板源码企业信息填报系统
  • 有口碑的赣州网站建设微信开放社区
  • 外贸网站做SEO电脑浏览器打不开网页是什么原因
  • 做网站需要下载啥google建站推广
  • 沈阳哪里有教做网站的会做网站怎么赚钱
  • iis如何做同时运行两个网站80端口做汽车网站费用
  • 网站规划与设计一千字网红营销模式
  • 西安 域名空间网站制作淘宝客网站主题下载
  • 网页制作与网站建设pdf网站开发前端和后端工作
  • 网站设计教学西安免费企业网站模板图片
  • 吉林省住房和城乡建设厅网站官网手机百度app免费下载
  • 微信开放平台网站应用营销网站建设的规则
  • 网站制作语言有哪些对接标准做好门户网站建设