重新开始---sgg-netty----1

命令模式和责任链模式。

----------------------------------------1-1-----------------------------------------------

-----------------------------------1-2-----------------------------------------------------

---------------------------------------------1-3-----------------------------------------------------


 

-----------------------------------------------------1-4---------------------------------------------------------

BIO:一个线程一个连接,没有缓冲区。

NIO:多个channel注册同一个selector,有缓冲区。

-----------------------------------1-5-----------------------------------------------------

 public static void main(String[] args) throws Exception {
        //线程池机制
        //思路
        //1. 创建一个线程池
        //2. 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        //创建ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服务器启动了");
        while (true) {
            System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
            //监听,等待客户端连接
            System.out.println("等待连接....");
            final Socket socket = serverSocket.accept();
            System.out.println("连接到一个客户端");

            // 这块是阻塞的要是有连接来了就创建线程去读取数据
            //就创建一个线程,与之通讯(单独写一个方法)
            newCachedThreadPool.execute(new Runnable() {
                public void run() { //我们重写
                    //可以和客户端通讯
                    handler(socket);
                }
            });
        }
    }

    //编写一个handler方法,和客户端通讯
    public static void handler(Socket socket) {

        try {
            System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
            byte[] bytes = new byte[1024];
            //通过socket 获取输入流
            InputStream inputStream = socket.getInputStream();

            //循环的读取客户端发送的数据
            while (true) {

                System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());

                System.out.println("read....");
               int read =  inputStream.read(bytes);
               if(read != -1) {
                   System.out.println(new String(bytes, 0, read
                   )); //输出客户端发送的数据
               } else {
                   break;
               }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("关闭和client的连接");
            try {
                socket.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

简单的BIO模型。

重点:阻塞的两个方法就是read和accept,经典啊。两个while都是阻塞的。主线程去监听,不断的切换子线程去新建连接。

socket.accept。

inputstream.read。

-----------------------------------1-6-----------------------------------------------------

总结。

问题分析:

--------------------------------------------------1-7---------------------------------------------------------------

NIO的主要组件:通道,缓冲区和selector。

主要是一个selector是一个线程,多个通道也就是socket可以注册到一个selector上面。

找个就是NIO的好处。

每一个通道对应一个buffer。  

NIO是同步非阻塞的。

select可以注册很多通道,每个通道对应一个请求。

通道没有任务我这个线程还可以执行其他的任务。

-----------------------------------1-8-----------------------------------------------------

代码:

NIO的Buffer是有很多的种类的。

package com.atguigu.nio;

import java.nio.IntBuffer;

public class BasicBuffer {
    public static void main(String[] args) {

        //举例说明Buffer 的使用 (简单说明)
        //创建一个Buffer, 大小为 5, 即可以存放5个int
        IntBuffer intBuffer = IntBuffer.allocate(5);
        //向buffer 存放数据
//        intBuffer.put(10);
//        intBuffer.put(11);
//        intBuffer.put(12);
//        intBuffer.put(13);
//        intBuffer.put(14);
        for(int i = 0; i < intBuffer.capacity(); i++) {
            intBuffer.put( i * 2);
        }
        //如何从buffer读取数据
        //将buffer转换,读写切换(!!!)
        /*
        public final Buffer flip() {
        limit = position; //读数据不能超过5
        position = 0;
        mark = -1;
        return this;
    }
         */
        intBuffer.flip(); // 方法很主要 buffer的读写切换的
        intBuffer.position(1);//1,2
        System.out.println(intBuffer.get());
        intBuffer.limit(3);
        while (intBuffer.hasRemaining()) {
            System.out.println(intBuffer.get());
        }
    }
}
 System.out.println(intBuffer.get());
// get是只读取下一位

BIO是流处理数据,NIO是块处理数据。

如何为非阻塞的,数据缓冲区到一定的量才会去读取。

--------------------------------------------------------------1-9--------------------------------------------------------------

0

重点:

1.每个channel都有一个buffer

2.一个selector对应一个线程。一个线程对应对应多个channel。

selector会根据不同的事件就是关心的读取?写入?还是连接?在各个通道上切换。

Buffer可以双向,channel也可以双向。

-----------------------------------1-10-----------------------------------------------------

发布了374 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_28764557/article/details/104854438