如果我會寫:如何檢測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