如果我会写:如何检测Selector.wakeup呼叫
int selectedChannels = selector.select(); Set selectedKeys = selector.selectedKeys(); if (selectedChannels != selectedKeys.size()) { // Selector.select() returned because of a call to Selector.wakeup() // so do synchronization. } // Continue with handling selected channels.
将它正确地检测到唤醒打电话?
Backgroundinformation:
我正在写的大部分时间只接收一个文件包,并将它们存储服务器。很少有应用程序需要发送一个特殊的数据包。为此,它启动(从不同的线程)到服务器套接字连接:
SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(new InetSocketAddress(InetAddress.getLocalHost(), PORT)); selector.wakeup(); SelectionKey key = channel.register(selector, SelectionKey.OP_CONNECT);
的问题是,SelectableChannel.register()如果主线程已经在Selector.select可能会阻塞()。为了防止这种情况发生,我调用Selector.wakeup()让主线程从select()过早返回。为了确保其他线程有机会完成注册调用,我将不得不同步主线程,但是我必须在之后每从select()返回。如果我能够通过唤醒()调用来检测它是否从select()返回,那么我可以针对这种情况优化它。
因此,理论上最好的代码片段应该可以工作,但我想知道它是否会这样做,因为它依赖于某些未指定的行为?
感谢您的任何提示。
你想避免锁的动机是什么?难道你担心执行时间,或者你是否在很多地方调用select(),并希望避免代码重复? – 2008-12-02 14:30:16
我很担心执行时间,尽管select()和register()已经在已注册的键上同步,但这可能是一个争议点。 – BugSlayer 2008-12-02 14:46:11
同意,担心这是过早优化的一个典型例子。除非你真的在谈论单微秒公差,否则你不会注意到任何放缓。我会用锁来回答一个问题。 – 2008-12-02 16:42:35