结论: register得放在select之前进行
Thread Dump信息:
"Poller-1" prio=6 tid=0x040f0400 nid=0x408 runnable [0x044df000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.j
ava:295)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelector
Impl.java:277)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:158)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
- locked <0x23b7df70> (a sun.nio.ch.Util$2)
- locked <0x23b7df60> (a java.util.Collections$UnmodifiableSet)
- locked <0x23b7dd40> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at com.zhh.nio.NioServer$Poller.run(NioServer.java:132)
at java.lang.Thread.run(Thread.java:722)
"Poller-0" prio=6 tid=0x040f0000 nid=0x14e4 runnable [0x0439f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.j
ava:295)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelector
Impl.java:277)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:158)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
- locked <0x23b77a98> (a sun.nio.ch.Util$2)
- locked <0x23b77a20> (a java.util.Collections$UnmodifiableSet)
- locked <0x23b76aa0> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at com.zhh.nio.NioServer$Poller.run(NioServer.java:132)
at java.lang.Thread.run(Thread.java:722)
"Acceptor" prio=6 tid=0x040ef800 nid=0x1250 waiting for monitor entry [0x03f1f00
0]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.SelectorImpl.register(SelectorImpl.java:133)
- waiting to lock <0x23b7df60> (a java.util.Collections$UnmodifiableSet)
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSele
ctableChannel.java:207)
- locked <0x23b8da18> (a java.lang.Object)
at java.nio.channels.SelectableChannel.register(SelectableChannel.java:2
77)
at com.zhh.nio.NioSession.register(NioSession.java:50)
at com.zhh.nio.NioServer$Poller.register(NioServer.java:123)
at com.zhh.nio.NioServer.handleNewSession(NioServer.java:222)
at com.zhh.nio.NioServer$Acceptor.run(NioServer.java:236)
at java.lang.Thread.run(Thread.java:722)
Code层面:
select:
private int lockAndDoSelect(long timeout) throws IOException {
synchronized (this) {
if (!isOpen())
throw new ClosedSelectorException();
synchronized (publicKeys) {
synchronized (publicSelectedKeys) {
return doSelect(timeout);
}
}
}
}
register:
protected final SelectionKey register(AbstractSelectableChannel ch,
int ops,
Object attachment)
{
if (!(ch instanceof SelChImpl))
throw new IllegalSelectorException();
SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
k.attach(attachment);
synchronized (publicKeys) {
implRegister(k);
}
k.interestOps(ops);
return k;
}
分享到:
相关推荐
4. **选择事件**:接着,通过`selector.select()`或`selector.select(timeout)`方法,Selector会阻塞等待,直到至少有一个已注册的通道有我们关心的事件发生,或者达到指定的超时时间。返回值表示有多少个通道处于...
`select()`方法实际上会调用操作系统API,阻塞等待直到有事件发生。源码分析需要深入理解这些底层实现,但这里仅做概念性介绍。 通过深入学习和理解Selector机制,开发者可以有效地设计和实现高性能的服务器应用,...
- **选择事件**:一旦通道被注册,我们就可以调用Selector的`select()`或`select(long timeout)`方法来等待和获取已经准备好的事件。这些事件被封装在SelectionKey对象中。 - **处理事件**:从Selector返回的迭代...
Java NIO(New IO)是Java 1.4版本引入的一个新特性,它提供了一种新的方式来处理I/O操作,相比传统的IO模型,NIO具有更好的性能和更高的效率。Selector是Java NIO中的核心组件之一,它允许单个线程处理多个通道...
selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); if (key....
此外,NIO不适用于短连接和低并发场景,因为创建和销毁通道及缓冲区会带来额外开销。 通过以上介绍,我们可以看出Java NIO是一个强大且灵活的I/O框架,为开发者提供了处理并发连接和大量I/O操作的有效工具。理解并...
- 选择事件:调用`selector.select()`或`selector.select(long timeout)`来等待和获取就绪的事件。 - 处理事件:遍历选择器返回的`selectedKeys`集合,对每个就绪的通道进行相应的读写操作。 - 关闭资源:操作...
Java NIO的核心组件包括Channel(通道)、Buffer(缓冲区)和Selector(选择器)。 - **Channel**:通道用于连接源和目的地,支持数据的读写操作。与传统的流不同,通道支持双向通信,并且可以通过非阻塞的方式进行...
Java NIO(非阻塞I/O)中的Selector是一个核心组件,它允许单个线程处理多个通道(channels)上的I/O事件。Selector的角色就像一个交通指挥员,能够监控多个通道并决定哪个通道准备好进行读写操作,从而提高系统的...
7. **Selector.select()**:阻塞等待至少一个通道准备就绪,然后返回一组键表示哪些通道已准备就绪。 8. **read()** 和 **write()** 方法:用于从通道读取数据到缓冲区,或从缓冲区写入数据到通道。 通过这个实例,...
在这些示例中,`selector.select()`会阻塞直到至少有一个通道准备好进行读、写或接受连接。然后,我们遍历选择器的`selectedKeys()`集合,处理相应的事件。在读取事件中,通常从通道读取数据到缓冲区,然后处理或...
4. 进入一个无限循环,调用`selector.select()`等待客户端连接请求。 5. 当有新的连接请求时,通过`key.channel()`获取SocketChannel,然后与客户端建立连接。 6. 将新建立的SocketChannel也注册到Selector,关注...
在主循环中,服务端通过`selector.select()`等待事件的发生,当有事件时,遍历选择器的已选择键集合,判断是接受连接事件还是读事件,并相应地处理客户端连接和读取数据。 客户端的NIO实现通常包括创建一个`...
selector.select(); // 获取并迭代所有已选择的键 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); // 移除已处理的...
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { // 选择就绪的事件 selector.select(); // 获取就绪的事件集合 Iterator<SelectionKey> it = selector.selectedKeys()....
3. 将ServerSocketChannel注册到Selector,指定感兴趣的操作,例如接受连接操作OP_ACCEPT,通过ssc.register(selector, SelectionKey.OP_ACCEPT)。 4. 使用Selector.select()方法进行轮询,获取有事件发生的...
4. **处理事件**:调用`selector.select()`等待事件,然后处理就绪的通道。 ```java Set<SelectionKey> keys = selector.selectedKeys(); for (SelectionKey key : keys) { if (key.isReadable()) { // 处理读事件...
4. **选择器使用**:通过`Selector.open()`创建选择器,然后用`channel.register(selector, interestOps)`方法将感兴趣的通道和事件注册到选择器上。`interestOps`通常包含`SelectionKey.OP_READ`和`SelectionKey.OP...
selector.select(); Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); if (key.isAcceptable()) { SocketChannel ...
在 Java 中,Selector 的实现基于操作系统的 select() 和 poll() 系统调用,提供了高效的 I/O 操作能力。 以下是一个使用 Selector 的完整示例: ```java Selector selector = Selector.open(); channel....