JAVA阻塞(IO)和非阻塞(NIO)

查看这篇文章,了解更多关于Java的阻塞和非阻塞替代创建套接字的信息。

套接字使用TCP / IP传输协议,是两台主机之间的最后一块网络通信。 您通常不必处理它们,因为它们之上构建了协议,如HTTP或FTP; 但是,了解它们的工作方式非常重要。

TCP:它是一种可靠的数据传输协议,可确保发送的数据完整且正确,并且需要建立连接。Java提供了一种阻塞和非阻塞替代方法来创建套接字,并且根据您的要求,您可以考虑使用其中一个。

Java IO

Java阻塞IO API包含在Java.net包下的JDK中,通常最简单易用。

此API基于可以读取或写入的字节流和字符流。 没有可用于前后移动的索引,就像在数组中一样,它只是一个连续的数据流。

每次客户端请求连接到服务器时,它都会阻塞一个线程。 因此,如果我们希望有许多同时连接,我们必须创建足够大的线程池。

1. 使用给定端口创建ServerSocket以进行侦听。

2. 当调用accept()并开始监听客户端连接时,服务器将阻塞。

3. 如果客户端请求连接,则accept()返回一个Socket。

4. 现在,我们可以从客户端(InputStream)读取并将数据发送回客户端(OutputStream)。

如果我们想允许多个连接,我们必须创建一个线程池:

如您所见,此API有一些限制。 我们将无法接受比机器中可用线程更多的连接。 因此,如果您希望有许多连接,则需要一个替代方案。

Java NIO

Java.nio是用于套接字连接的非阻塞API,这意味着您对可用线程的数量并不紧密。 使用此库,一个线程可以同时处理多个连接。

Channel::通道是输入和输出流的组合,因此它们允许您进行读写,并且它们使用缓冲区来执行这些操作。

Buffer:它是一块内存,用于从通道读取并写入其中。 当你想从Buffer中读取数据时,需要调用flip(),以便将pos设置为0。

1. 在第1行,pos将等于写入Buffer的字节数。

2. 在第3行,调用flip()将位置设置为0并限制先前写入的字节数。

3. 在第5行,它一次从缓冲区读取一个字节到极限。

4. 最后,在第7行,我们清除缓冲区。

Selector:选择器可以注册多个通道,并检查哪些通道已准备好接受新连接。 与阻塞IO的accept()方法类似,当调用select()时,它将阻塞应用程序,直到Channel准备好进行操作。 由于Selector可以注册多个通道,因此只需要一个线程来处理多个连接。

Selection Key:它包含特定通道的属性(兴趣集,就绪集,选择器/通道和可选的附加对象)。 选择键主要用于了解通道的当前兴趣(isAcceptable(),isReadable(),isWritable()),获取通道并对该通道进行操作。

下面我们将使用Echo Socket Channel服务器来展示NIO的工作原理。

 

1. 从第1行到第3行,创建了ServerSocketChannel,您必须明确地将其设置为非阻塞模式。 套接字还配置为监听端口8080。

2. 在第5行和第6行,创建一个Selector,并在Selector上注册ServerSocketChannel,其中SelectionKey指向ACCEPT操作。

3. 为了使应用程序始终保持监听,阻塞方法select()位于无限while循环内,select()将在选择至少一个通道时返回,唤醒唤醒()或线程被中断。

4. 然后,在第10行,从选择器返回一组键,我们将遍历它们以执行就绪通道。

1. 每次创建新连接时,isAcceptable()都将为true,并且新的Channel将注册到Selector中。

2. 为了跟踪每个通道的数据,将它放在一个Map中,其中套接字通道作为键和ByteBuffers列表。

3. 然后,选择器将指向READ操作。

 

1. 在读取块中,将检索通道,并将传入的数据写入ByteBuffer。

2. 在第6行,我们检查连接是否已关闭。

3. 在第9行和第10行,缓冲区设置为flip()读取模式并添加到Map。

4. 然后,调用interestOps()以指向WRITE操作。

1. 再一次,检索通道以便将保存在Map中的数据写入其中。

2. 然后,我们将Selector设置为READ操作。

如果连接关闭,通道将从Map中删除,我们关闭通道。

Java IO Vs. NIO

IO和NIO之间的选择取决于用例。 对于更少的连接和简单的解决方案,IO可能更适合您。 然而,如果你想要能够同时处理数千个连接的更高效的东西,NIO可能是更好的选择,但请记住它会引入很多代码复杂性。 但是,有一些框架,如Netty或Apache MINA,它们构建在NIO之上,并隐藏了编程的复杂性。

如JAVA上遇到什么不懂的,可以私聊我!

posted @ 2019-08-21 13:50  科技光头强哥  阅读(4745)  评论(0编辑  收藏  举报