JAVA NIO中selectedKeys返回的键集,对其中的SelectionKey执行操作之后,是否需要在selectedKeys()中对其执行remove 操作

今天一个东西需要用到java nio的东西。在网上查了一下资料,发现有Apache的Mina,Netty等,感觉JDK中带的NIO有点鸡肋啊。之前看过这部分的内容,但好长一段时间没有用,也就忘得七七八八了。如今是温故而知新,但其中遇到了些疑问:

先贴上代码吧:

public static void main(String[] args) throws Exception{

		Thread sh=new Thread(new Runnable() {
			public void run(){
				try{
					ServerSocket ss=new ServerSocket(3000);
					Socket client=ss.accept();
					OutputStream os=client.getOutputStream();
					while(true){
						os.write("Helloworld".getBytes());
						Thread.sleep(1000);
					}
				}catch(Exception e){
					e.printStackTrace();
				}

			}
		});
		sh.start();

		SocketChannel sc=SocketChannel.open();
		sc.socket().connect(new InetSocketAddress("localhost",3000) );
		sc.configureBlocking(false);
		Selector selector=Selector.open();
		sc.register(selector,SelectionKey.OP_READ);

		ByteBuffer byteBuffer=ByteBuffer.allocate(1000);
		while(true){
			if(selector.select()>0){
				Set<SelectionKey> sks=selector.selectedKeys();

				for(SelectionKey key:sks){
					if(key.isReadable()){
						System.out.println("is Readable() ");
						SocketChannel isc=(SocketChannel)key.channel();
						isc.read(byteBuffer);
					}
					sks.remove(key);
				}
			}
			System.out.println("return from select() ");
		}
	}

  

关于是否需要sks.remove(key)这一行呢。

按照上面运行的结果:

is Readable()
return from select()
is Readable()
return from select()
is Readable()
return from select()
is Readable()
return from select()

然后把sks.remove(key)这一行注释掉,再次运行:

is Readable()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
return from select()
...

说明了,如果不对已经处理完的SelectionKey在selectedKyes中执行remove操作的话。下一次select()操作将会直接返回,但其返回的值是0

时间: 2024-11-09 00:33:33

JAVA NIO中selectedKeys返回的键集,对其中的SelectionKey执行操作之后,是否需要在selectedKeys()中对其执行remove 操作的相关文章

也讲Java NIO

也讲Java NIO 一点开场白 百度搜索java nio,前面的几个帖子总是从各种基础概念介绍起,通道.缓冲区.选择器- 然后看着看着就晕了,所以,经过一晚上的研究,我想从自己的理解讲讲nio. 一.单线程的通信 在没有nio之前,java妥妥的可以进行CS项目间的通信,来个最简单的例子.(懒得写,抄了段) server 端 package nio.nonio; import java.io.BufferedReader; import java.io.BufferedWriter; impo

java nio学习三:NIO 的非阻塞式网络通信

一.阻塞和非阻塞 传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务.因此,在完成网络通信进行 IO 操作时,由于线程会阻塞,所以服务器端必须为每个客户端都提供一个独立的线程进行处理,当服务器端需要处理大量客户端时,性能急剧下降.Java NIO 是非阻塞模式的.当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务.线程通常将非阻塞 IO 的空闲时间用于在其他通道上

java nio使用方法(转)

最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下,顺便写点东西,就当是自己学习 Java NIO的笔记了.本文为NIO使用及原理分析的第一篇,将会介绍NIO中几个重要的概念. 在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的I/O速度

Java NIO使用及原理分析(3) 来自网上资料整理

缓冲区的分配 在 前面的几个例子中,我们已经看过了,在创建一个缓冲区对象时,会调用静态方法allocate()来指定缓冲区的容量,其实调用 allocate()相当于创建了一个指定大小的数组,并把它包装为缓冲区对象.或者我们也可以直接将一个现有的数组,包装为缓冲区对象,如下示例代码所 示: public class BufferWrap { public void myMethod() { // 分配指定大小的缓冲区 ByteBuffer buffer1 = ByteBuffer.allocat

Java nio 笔记:系统IO、缓冲区、流IO、socket通道

一.Java IO 和 系统 IO 不匹配 在大多数情况下,Java 应用程序并非真的受着 I/O 的束缚.操作系统并非不能快速传送数据,让 Java 有事可做:相反,是 JVM 自身在 I/O 方面效率欠佳.操作系统与 Java 基于流的 I/O模型有些不匹配.操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取(DMA)的协助下完成的.而 JVM 的 I/O 操作类喜欢操作小块数据--单个字节.几行文本.结果,操作系统送来整缓冲区的数据,java.io 包的流数据类再花大量时间

Java NIO使用及原理分析(三)(转)

在上一篇文章中介绍了缓冲区内部对于状态变化的跟踪机制,而对于NIO中缓冲区来说,还有很多的内容值的学习,如缓冲区的分片与数据共享,只读缓冲区等.在本文中我们来看一下缓冲区一些更细节的内容. 缓冲区的分配 在前面的几个例子中,我们已经看过了,在创建一个缓冲区对象时,会调用静态方法allocate()来指定缓冲区的容量,其实调用 allocate()相当于创建了一个指定大小的数组,并把它包装为缓冲区对象.或者我们也可以直接将一个现有的数组,包装为缓冲区对象,如下示例代码所示: [java] view

C#在Dictionary中使用枚举作为键

Enum类型没有实现IEquatable接口,Dictionary中使用Enum作为键时,将发生装箱,使效率降低. 此时可用Dictionary中一个接收IEqualityComparer<T>类型的重载版本来避免对枚举的装箱操作. 先定义一个泛型的比较器实现IEqualityComparer<T>. 1 public class EnumComparer<T> : IEqualityComparer<T> where T : struct 2 { 3 #r

ORACLE中添加删除主键

本文转自:http://blog.chinaunix.net/uid-17079336-id-2832443.html 1.创建表的同时创建主键约束(1)无命名create table student (studentid int primary key not null,studentname varchar(8),age int);(2)有命名create table students (studentid int ,studentname varchar(8),age int,constr

java mybatis中insert 操作 返回主键的小技巧。。。。

第一种方式: 在实体类的映射文件 "*Mapper.xml" 这样写: <insert id="insertvmatedic" keyColumn="mdid" useGeneratedKeys="true" keyProperty="mdid" parameterType="Vmaterialdictionary"> insert into vmaterialdiction