xulingbo / xulingbo.github.io

蓝色冰火
http://xulingbo.net
528 stars 145 forks source link

深入分析 Java I/O 的工作机制 #11

Open xulingbo opened 9 years ago

xulingbo commented 9 years ago

摘要:I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动。这个流动的过程中都涉及到 I/O 问题,可以说大部分 Web 应用系统的瓶颈都是 I/O 瓶颈。本文的目的正是分析 I/O 的内在工作机制,你将了解到:Java 的 I/O 类库的基本架构;磁盘 I/O 工作机制;网络 I/O 的工作机制;其中以网络 I/O 为重点介绍 Java Socket 的工作方式;你还将了解到 NIO 的工作方式,还有同步和异步以及阻塞与非阻塞的区别,最后我们将介绍一些常用的关于 I/O 的优化技巧。

详细http://www.ibm.com/developerworks/cn/java/j-lo-javaio/

daoxiangcun commented 8 years ago

好文,楼主在developerworks上发了不少文章啊

Qnmy commented 7 years ago

之前在看《深入分析Java Web技术内幕》中 “深入分析Java I/O 的工作机制” 这一章内容时,使用了里面的如下代码片段,做练习,发现代码存在问题。 NIO 工作代码示例

public void selector() throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);//设置为非阻塞方式
        ssc.socket().bind(new InetSocketAddress(8080));
        ssc.register(selector, SelectionKey.OP_ACCEPT);//注册监听的事件
        while (true) {
           /**
            *  缺少如下代码
            * 该方法注释:This method performs a blocking selection operation. It returns only after at least
            *    one channel is selected, this selector's wakeup method is invoked, or the current thread is
            *    interrupted, whichever comes first. 
            */
           selector.select();  
           /**
             * 缺少代码结束
             */
            Set selectedKeys = selector.selectedKeys();//取得所有key集合
            Iterator it = selectedKeys.iterator();
            while (it.hasNext()) {
                SelectionKey key = (SelectionKey) it.next();
                if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
                    ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel();
                 SocketChannel sc = ssChannel.accept();//接受到服务端的请求
                    sc.configureBlocking(false);
                    sc.register(selector, SelectionKey.OP_READ);
                    it.remove();
                } else if 
                ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                    SocketChannel sc = (SocketChannel) key.channel();
                    while (true) {
                        buffer.clear();
                        int n = sc.read(buffer);//读取数据
                        if (n <= 0) {
                            break;
                        }
                        buffer.flip();
                    }
                    it.remove();
                }
            }
        }
}

缺少了调用selector.select()方法,导致服务器端没能阻塞,客户端连接不上服务器端。 希望楼主有空看看,是不是真的有这个问题。

971829286 commented 5 years ago

深入分析java内幕-3中cname的全拼英文错误,请纠正。