private static Selector selector;
    static{
        try {
            selector=Selector.open();
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
    private InetSocketAddress socketAddress;
    private DatagramChannel channel = null;
    public void openDatagramChannel(String url, int port) throws Exception {
        channel = DatagramChannel.open();
        channel.socket().setSoTimeout(10000);
        channel.configureBlocking(false);
        socketAddress = new InetSocketAddress(url, port);
        channel.connect(socketAddress);
        SelectionKey key = channel.register(selector, SelectionKey.OP_WRITE);
    }    public void closeDatagramChannel() throws Exception {
        if (channel != null) {
            SelectionKey key = channel.keyFor(selector);
            if (key != null) key.cancel();
            channel.socket().disconnect();
            channel.socket().close();
            channel.disconnect();
            channel.close();
            channel = null;
        }
    }    public boolean connect(String host, int port) throws Exception {
        try {
            if (channel == null) openDatagramChannel(host, port);
            int num = selector.select();
            if (num == 0) return false;
            Set Keys = selector.selectedKeys();        //size=0?
            Iterator it = Keys.iterator();
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            if (it.hasNext()) {
                SelectionKey k = (SelectionKey) it.next();
                if ((k.readyOps() & SelectionKey.OP_WRITE)
                        == SelectionKey.OP_WRITE) {
                        //do something
                    it.remove();
                }               
            }
        } finally {
            closeDatagramChannel();
        }
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }
=============================================================
多线程运行上面程序会报告ConcurrentModificationException。这个很明显,在一个SELECTOR的情况下,SELECTOR在被多线程改变的时候,就出现ConcurrentModificationException错误。另外一个办法是每次openDatagramChannel的开一个SELECTOR。但这个问题在多线程,高并发的情况下引起了SELECTOR占据了所有文件句柄问题(65536),具体见http://www.zxbc.cn/html/20080401/32982.html。那么,在高并发的情况下。是开多个SELEcTOR,还是开一个?只一个,就出现上面情况ConcurrentModificationException.这个如何解决?
请HELP一下,一个人搞不定了

解决方案 »

  1.   

    只有一个SELECTOR的情况可以参考GUI的单线程模式,SELECTOR只能通过一个主线程来更新,其他线程想要更新SELECTOR就必须notify主线程,不过不知道这样效率能不能接受。
    好像JAVA 7会有更好的nio了
      

  2.   

    问题已经解决。目前是每次openDatagramChannel的开一个SELECTOR。但这个问题在多线程,高并发的情况下需要selector.CLOSE()不过这样就不能多路复用了。多路复用ConcurrentModificationException这个问题比较明显