java NIO 多线程

问题描述

public void run() { exitRequest = false ; while( !exitRequest) { try { // 初期化 socketChannel = SocketChannel.open() ; selector = Selector.open() ; socketChannel.socket().setReuseAddress( true) ; socketChannel.configureBlocking( false) ; socketChannel.socket().setReceiveBufferSize( RECV_BUFFER) ; selectionKey = socketChannel.register( selector, SelectionKey.OP_CONNECT) ; selectionKey.attach( new SocketNioControl( notifyObject, selector, socketChannel, selectionKey)) ; socketChannel.connect( inetAddress) ; int timer = 0 ; while( !socketChannel.isConnected()) { selector.select(100) ; if( exitRequest) { break ; } for( SelectionKey key : selector.selectedKeys()) { if( key.isConnectable()) { SocketChannel socketChannel = ( SocketChannel)key.channel() ; SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketChannel.finishConnect() ; key.interestOps( SelectionKey.OP_READ) ; socketControl.connect() ; break ; } } if( timer >= TIMER_CONNECT * 1000) { throw new ConnectException() ; } timer += 100 ; } try { while( !exitRequest) { selector.select() ; for( SelectionKey key : selector.selectedKeys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; if( key.isReadable()) { socketControl.read() ; } if( key.isWritable()) { socketControl.write() ; } } } } catch ( ConnectException ioex) { } catch ( CancelledKeyException ckex) { } } catch ( UnknownHostException uhex) { ErrorMessage.logging( uhex) ; } catch ( Exception ex) { ErrorMessage.logging( ex) ; } finally { try { for( SelectionKey key : selector.keys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketControl.disconnect() ; } if( selector != null) { selector.close() ; selector = null ; } for( int timer = 0; timer < TIMER_RETRY * 1000; timer += 100) { Thread.sleep( 100) ; if( exitRequest) { break ; } } } catch( IOException ioe) { } catch( InterruptedException iex) { } } } } 线程一直被占用,导致系统hungup.是哪里出问题呢?另外 selector.select() 的值一直是0;这一句是起什么作用的?

解决方案

处理完某个事件后记得重新注册感兴趣的操作。尤其是写操作,系统大部分时候都是可写的,因此你如果不取消对写的注册,那就会不停地得到写就绪事件,其实就是死循环了。请参考这个正确的写法:http://teasp.iteye.com/admin/blogs/1884408
解决方案二:
key拿出后要remove 初学者经常忘记这个 不remove会死循环的Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> itr = keys.iterator(); while (itr.hasNext()) { SelectionKey key = itr.next(); itr.remove();
解决方案三:
如果是hangup的话,你最好用jstack 看看挂在哪儿
解决方案四:
selector.select() 是不会返回零的 除非执行了wakeup。只有selector.select(timeout) 当超时以后没有有事件的channel,才会返回零,你是指的那个select,假设是selector.select() 返回0,有可能是错误的wakeup。key.interestOps( SelectionKey.OP_READ) ;这句code应该可以取消write只设置read了吧
解决方案五:
稍微仔细看了下,问题太多。

时间: 2024-09-19 10:13:02

java NIO 多线程的相关文章

理解Java NIO

基础概念 • 缓冲区操作 缓冲区及操作是所有I/O的基础,进程执行I/O操作,归结起来就是向操作系统发出请求,让它要么把缓冲区里的数据排干(写),要么把缓冲区填满(读).如下图 • 内核空间.用户空间  上图简单描述了数据从磁盘到用户进程的内存区域移动的过程,其间涉及到了内核空间与用户空间.这两个空间有什么区别呢?  用户空间就是常规进程(如JVM)所在区域,用户空间是非特权区域,如不能直接访问硬件设备.内核空间是操作系统所在区域,那肯定是有特权啦,如能与设备控制器通讯,控制用户区域的进程运行状

从Netty到EPollSelectorImpl学习Java NIO

终于可以在写了几篇鸡汤文后,来篇技术文章了,:),题图是Trustin Lee,Mina/Netty都是他搞的,对Java程序员尤其是写通讯类的都产生了巨大影响,向他致敬! 在上周查一个内存OOM的问题之前,我一直觉得自己对Java NIO应该还是比较懂的,君不见N年前我曾经写过一篇<NFS-RPC框架优化过程(从37K到168K)>(尴尬的发现,上次导blog记录的时候竟然丢了一些文章,于是这文章link就不是自己的blog了),从那优化经历来说理论上对Netty的原理应该已经是比较清楚了才

Java NIO 系列教程

Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.本系列教程将有助于你学习和理解Java NIO.感谢并发编程网的翻译和投递.  (关注ITeye官微,随时随地查看最新开发资讯.技术文章.)  [本文转载于 Java NIO 系列教程] Java NIO提供了与标准IO不同的IO工作方式:  Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channe

Java NIO 系列教程(转)

原文中说了最重要的3个概念,Channel 通道Buffer 缓冲区Selector 选择器其中Channel对应以前的流,Buffer不是什么新东西,Selector是因为nio可以使用异步的非堵塞模式才加入的东西.以前的流总是堵塞的,一个线程只要对它进行操作,其它操作就会被堵塞,也就相当于水管没有阀门,你伸手接水的时候,不管水到了没有,你就都只能耗在接水(流)上.nio的Channel的加入,相当于增加了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各

java Nio 异步操作(四)channel

Java NIO 的核心组成部分: 1.Channels 2.Buffers 3.Selectors 我们首先来学习Channels(java.nio.channels): 通道 1)通道基础 通道(Channel)是java.nio的第二个主要创新.它们既不是一个扩展也不是一项增强,而是全新.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效地传输数据. channel的jdk源码: 1 2 3 4 5

Java NIO 详解(二)

在我的上一篇文章JavaNIO详解(一)中介绍了关于标准输入输出NIO相关知识, 本篇将重点介绍基于网络编程NIO(异步IO). 异步IO 异步 I/O 是一种没有阻塞地读写数据的方法.通常,在代码进行 read() 调用时,代码会阻塞直至有可供读取的数据.同样, write()调用将会阻塞直至数据能够写入,关于同步的IO请参考另一篇文章Java IO. 另一方面,异步 I/O 调用不但不会阻塞,相反,您可以注册对特定 I/O 事件诸如数据可读.新连接到来等等,而在发生这样感兴趣的事件时,系统将

Java NIO 完全学习笔记(转)

本篇博客依照 Java NIO Tutorial 翻译,算是学习 Java NIO 的一个读书笔记.建议大家可以去阅读原文,相信你肯定会受益良多. 1. Java NIO Tutorial Java NIO,被称为新 IO(New IO),是 Java 1.4 引入的,用来替代 IO API的. Java NIO:Channels and Buffers 标准的 Java IO API ,你操作的对象是字节流(byte stream)或者字符流(character stream),而 NIO,你

java NIO 详解_java

Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中. Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情.当数据被写入到缓冲区时,线程可以继续处理它.从缓冲区写入通道也类似. S

Java NIO原理和使用

ava NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的. Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就