同步阻塞、同步非阻塞、异步非阻塞的代码层面理解

2018-11-07  本文已影响0人  sunshujie1990
        ServerSocket serverSocket = new ServerSocket(8080);
        Socket accept = serverSocket.accept();// 1
        InputStream inputStream = accept.getInputStream();
        BufferedReader br = new BufferedReader(new   
        InputStreamReader(inputStream));
        String s = br.readLine();// 2
        System.out.println(s);
        ServerSocketChannel channel = ServerSocketChannel.open();
// 通过channel的配置可以配置为非阻塞
        channel.configureBlocking(false);
        channel.socket().bind(new InetSocketAddress(8080));

        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
// 虽然是非阻塞,也有阻塞的地方,在selector.select()的时候, 如果没有事件发生,会阻塞在这里。
            selector.select();
            Set<SelectionKey> keys = selector.selectedKeys();
            for (SelectionKey key : keys) {
                if (key.isAcceptable()) {
// selector.select()已经阻塞了,这里客户端链接已经准备好了,所以会马上创建好tcp连接,这里是非阻塞的
                    SocketChannel client = channel.accept();
                    if (client == null) {
                        continue;
                    }
                    client.configureBlocking(false);
                    client.write(ByteBuffer.wrap("hello world".getBytes()));
// 给同一个selector注册客户端channel的read事件,因为一个selector能够注册多个channel,并且能够监听这些channel的accept,read,write等事件,所以叫做多路复用。
                    client.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel curClient = (SocketChannel) key.channel();
                    ByteBuffer bf = ByteBuffer.allocate(512);
// selector.select()的时候表明已经有数据过来了,所以这里是非阻塞
                    curClient.read(bf);
                    String s = new String(bf.array(), "UTF-8");
                    System.out.println(s);
                }
            }
        }
上一篇 下一篇

猜你喜欢

热点阅读