研究了一下NIO的非阻塞连接。。似乎有点问题。。
当服务端处理一个比较耗时的业务请求的时候,客户端是阻塞的。。
场景:2个客户端请求,在服务端分辨,第一个处理了10秒钟,在处理过程中,第二个请求进不来。
因为是轮询selector来获取处理的内容的,而两次请求是属于两个selector,第一个selector没有处理完,第二个就一直等待。。。。。。。。。这就有问题,不是并发了。。。
package com.test.nio;
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.nio.channels.spi.SelectorProvider;
import java.util.Date;
import java.util.Iterator;
public class NIONBServer {
public static int count = 0;
/**
* @param args
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel server = ServerSocketChannel.open();
Selector acceptSelector = SelectorProvider.provider().openSelector();
server.socket().bind(new InetSocketAddress(8787));
server.configureBlocking(false);
server.register(acceptSelector, SelectionKey.OP_ACCEPT);
for (;;) {
acceptSelector.select();
Iterator<SelectionKey> iter = acceptSelector.selectedKeys().iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
if (key.isAcceptable()) {
ServerSocketChannel serverc = (ServerSocketChannel) key.channel();
SocketChannel channel = serverc.accept();
channel.configureBlocking(false);
// channel.register(acceptSelector, SelectionKey.OP_READ);
channel.register(acceptSelector, SelectionKey.OP_WRITE);
} else if (key.isReadable()) {
if (0 == count++) {
System.out.println("Count=" + count + " Sleep=" + 5000);
Thread.sleep(10000);
}
System.out.println("Count=" + count);
SocketChannel channel = (SocketChannel) key.channel();
channel.register(acceptSelector, SelectionKey.OP_WRITE);
} else if (key.isWritable()) {
if (0 == count++) {
System.out.println("Count=" + count + " Sleep=" + 5000);
Thread.sleep(10000);
}
System.out.println("Count=" + count);
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer block = ByteBuffer.allocate(100);
block = ByteBuffer.wrap(new Date().toString().getBytes());
channel.write(block);
channel.close();
}
}
}
}
}
package com.test.nio;
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.SocketChannel;
import java.util.Iterator;
public class NIOClient {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
SocketChannel client = SocketChannel.open();
client.configureBlocking(false);
Selector selector = Selector.open();
client.register(selector, SelectionKey.OP_CONNECT);
InetSocketAddress ip = new InetSocketAddress("localhost", 8787);
client.connect(ip);
ByteBuffer buffer = ByteBuffer.allocate(1024);
FOR: for (;;) {
selector.select();
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending())
channel.finishConnect();
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
int count = channel.read(buffer);
System.out.println("count:" + count);
if (count > 0) {
buffer.clear();
System.out.println(new String(buffer.array()).trim());
} else {
client.close();
break FOR;
}
}
}
}
}
}
谁能帮我看看代码问题出现在什么地方??
如果服务端接受请求后启动新的线程作处理,那和传统的多线程阻塞的模式就没有区别了,还是需要消耗线程调度资源。
分享到:
相关推荐
总的来说,这个NIO服务端和客户端的例子可以帮助我们深入理解Java NIO和Netty框架的工作原理,学习如何构建高效、可靠的网络应用。通过实践和分析这个示例代码,我们可以更好地掌握异步I/O、事件驱动编程以及Netty...
该JAVA NIO项目包含server服务端完整项目源码、client客户端项目工程源码。
本教程将深入讲解如何使用Java NIO实现非阻塞服务端与客户端的通信。 1. **Java NIO基础** - **通道(Channels)**:NIO中的通道类似于传统IO的流,但它们可以同时读写,并且支持非阻塞操作。 - **缓冲区...
- 讨论NIO实现可能存在的问题,例如复杂性较高,以及可能的改进方案。 同步与异步、阻塞与非阻塞的概念也是面试中常见的知识点: - 同步强调的是调用的顺序性和可靠性,而异步则允许任务并行处理,依赖于事件或回...
详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址http://blog.csdn.net/g290095142/article/details/77848088
**JAVA NIO 异步通信模板服务端** Java NIO(New Input/Output)是Java在J2SE 1.4版本中引入的一个新特性,它提供了与标准I/O完全不同的编程模型,尤其是在处理大量并发连接时,NIO展现出了更高的效率。本模板...
- **线程池**:对于大量并发连接,使用线程池处理每个连接的业务逻辑,避免线程过度创建。 - **异常处理**:确保正确处理各种可能的异常情况,如连接中断、数据传输错误等。 - **关闭资源**:在完成操作后,记得...
这个简单的例子展示了如何使用Java NIO实现服务器和客户端的基本通信流程,但实际应用中可能还需要处理异常、数据解析、心跳检测等复杂逻辑。理解NIO的核心概念和API,对于构建高效、可扩展的网络应用至关重要。
Java NIO(New IO)是Java 1.4版本引入的一个新特性,它提供了一种新的I/O操作方式,与传统的BIO(Blocking IO)模型相比,NIO具有更高的并发性能,尤其在处理大量连接请求时更为明显。NIO的核心在于非阻塞I/O,即在...
基于事件的 NIO 多线程服务器
本Demo展示了如何在服务端使用NIO来处理请求,让我们一起深入学习这个关键知识点。 首先,NIO的核心组件包括: 1. **Buffer(缓冲区)**:在NIO中,数据读写是通过Buffer进行的。Buffer是一个固定大小的字节数组,...
在NIO中,服务端通常创建一个主线程负责选择和调度事件,然后根据需要创建工作线程来处理具体任务,这样可以避免主线程被某个耗时操作阻塞。 描述中提到了"本工程源码",这通常意味着可以通过查看和分析代码来理解...
import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.Scanner; /** * 符合TCP协议,非阻塞IO NIO完成对应的客户端代码 * @Author kk * @Date 2020/3/16 15:10 */ public cl
NIO与IO之间的区别,NIO优点在于是异步不阻塞,这样比IO更加的给力。
在开始本节之前,我先讲一个亲身经历的故事:曾经有两个项目组同时用到了NIO编程技术,一个项目组选择自己开发NIO服务端,直接使用JDK原生的API,结果2个多月过去了,他们的NIO服务端始终无法稳定,问题频出。...
标题“nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio”表明这个压缩包包含了一个关于Java NIO的实例,特别是关于NIO套接字(Socket)的编程示例。NIO套接字是Java NIO库中用于网络通信的关键组件,它们允许...
通常,我们会创建一个缓冲区,读取SocketChannel中的数据,然后进行业务逻辑处理: ```java SocketChannel clientChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int ...
jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU...