解决方案 »
- jar包冲突了,跪求大神帮助啊!到底是哪个jar包冲突?服务器用的是tongweb
- 模糊搜索,返回结果字把搜索关键字替换成红色(如百度的搜索)。 如何实现?
- 还望各位高手推荐一本关于JAVA SOA的书籍
- 重复提交的问题
- 请问 xerces 与 sax 是什么关系, xerces 是什么啊?
- struts2 拦截器调用后action属性失效
- js 计算时间差的问题 费解中~~~
- 关于net.sf.hibernate.MappingException: Unknown entity class的问题,请各位大侠帮忙,谢谢!
- 怎么在Struts的一个jsp处理两个actionForm?
- service层查询的对象如何让对象变成游离态
- java新人,请帮我解释下如下的代码程序
- 读取文件时报[java.net.SocketException: Connection reset]
只要socket空闲就会触发这个事件,网上了解到基本95%以上时间都会触发这个事件。
所以网上都是推荐有数据写入时才临时注册这个事件,发送数据后再取消这个事件。
引用火龙果的话:“有一些 NIO 框架就很少注册 OP_WRITE 事件的,直接写入,如果不适合时就会产生阻塞直到能写为止。
OP_WRITE 比 OP_READ 等事件处理麻烦很多,一不小心就会对性能产生严重的影响。 ”
关于OP_WRITE事件进一步了解
不对OP_WRITE进行处理的样例:
while (bb.hasRemaining()) {
socketChannel.write(bb);
}
这样写在大多数的情况下都没有什么问题。但是在客户端的网络环境很糟糕的情况下,服务器会遭到很沉重的打击。
因为如果客户端的网络或者是中间交换机的问题,使得网络传输的效率很低,这时候会出现服务器已经准备好的返回结果无法通过TCP/IP层传输到客户端。这时候在执行上面这段程序的时候就会出现以下情况:
(1) bb.hasRemaining()一直为“true”,因为服务器的返回结果已经准备好了。
(2) socketChannel.write(bb)的结果一直为0,因为由于网络原因数据一直传不过去。
(3) 因为是异步非阻塞的方式,socketChannel.write(bb)不会被阻塞,立刻被返回。
(4) 在一段时间内,这段代码会被无休止地快速执行着,消耗着大量的CPU的资源。事实上什么具体的任务也没有做,一直到网络允许当前的数据传送出去为止。
private void writeable(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
BufferManager manager = (BufferManager) key.attachment(); int len = manager.outputWriteBuffer(socketChannel);
if (len == EOF_FLAG) {
throw new ConnectException("close channel.");
} if (manager.isCompleteWrite()) { // 代码1
manager.rest();
synchronized (ioSelectorsSyns.get(key.selector())) {
key.selector().wakeup();
key.interestOps(SelectionKey.OP_READ);
}
}
}
这里每次都会去检测缓冲是否已经写完,写完后立即取消掉这个管道的写事件,没有就继续等下次可写时再写。决不能阻塞掉NIO的选择器线程。