研究了一下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项目包含server服务端完整项目源码、client客户端项目工程源码。
Java NIO非阻塞服务端与客户端相互通信 每行代码都有注释, 看完后,会让你对非阻塞有一清楚的认识.
详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址http://blog.csdn.net/g290095142/article/details/77848088
JAVA NIO 异步通信模板服务端
第三,在 Java 7 中,NIO 有了进一步的改进,也就是 NIO 2,引入了异步非阻塞 IO 方式,也有很多人叫它 AIO(Asynchronous IO)
这是一个用java NIO 实现的简单多线程服务器有客户端例子,仅供学习参考。
JAVA.NIO 异步长连接客户端与服务端都有,大家可以看看,另不知道怎么样将客户端读取的BUFF后的数据进行处理可以给出修改吗?
基于事件的 NIO 多线程服务器
JAVA.NIO 异步长连接客户端与服务端都有,大家可以看看,另不知道怎么样将客户端读取的BUFF后的数据进行处理可以给出修改吗?
服务端以NIO的方式处理请求的Demo,源码及详细注释
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服务端始终无法稳定,问题频出。...
java NIO 创建的服务端,能够异步响应客户端的请求,客户端采用nio异步请求服务端,通信之间的乱码使用charset解决
jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU...
基于nio 简易聊天室的服务端 客户端,有界面
1.1 Dubbo和SpringCloud的关系? Dubbo是SOA时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断 而SpringCloud诞生于微服务架构时代,...默认使用NIONetty框架 1.5 Dubbo是什么? Dubbo 是一个分布式
Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...