网易公开课(4)5G物联网时代

NIO与BIO

IO inputStream  outStream  文件操作流

网络流

通信:就是将数据写到相应的端口(socket)

等待客户端链接(accept())返回一个socket,

通过socket进行接受数据(getInputStream())   缓冲流(输入流(getInputStream))

client

 

应用场景

设备与server间 的通信

心跳的通信

及时状态的上报

服务端与客户端的远程连接的操作。(服务端要反向的向客户端进行数据的返回)

双向的通信

 

BIO中的阻塞

accept()方法是阻塞的

readLine()第二次阻塞(会将后面的连接堵塞):只要是第一个没有完成,就会一直的等下去

 

改进:多家几个,处理对象(多线程)

采用线程池

 

 

public class Server {
    public static void main(String[] args) {
        int port = 8080;
        // 声明线程池
        BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>();
        Executor executor = new ThreadPoolExecutor(10, 10000, 5,
                TimeUnit.SECONDS, blockingQueue);
        // 创建一个服务端,这里使用了Java 7的try-with-resource简化语法
        try(ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("server 启动...");
            while (true) { // 死循环
                // 这里会阻塞,直到有新的连接进来
                Socket socket = serverSocket.accept();
                // 有新的连接,就创建一个新的Task,丢进线程池。
                executor.execute(() -> {
                    try(BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
                        // 读取并打印数据
                        System.out.println("server 收到: " + reader.readLine());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
」}

 

public class Client {
    public static void main(String[] args) {
        int port = 8080;
        try(
                Socket socket = new Socket("127.0.0.1", 8080);
                PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                ) {
            writer.println("hi,这是client");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用Java多线程和BIO的网络通信方式,是Tomcat的基本原理。它的优势是模型简单,很容易就能实现,而且也能很好的工作。不过也有一定的劣势,就是不能承受太大的并发量。

一方面一旦并发量超过阻塞队列的容量,线程池就会执行拒绝策略;另一方面,每个线程在处理IO的时候其实是阻塞的,一旦处理IO的时间过长,就会阻塞很久,导致后面的Task需要等很久。

 

 

下面我们将用NIO来实现相同的功能。

读IO流时:

流     的本质是阻塞的!

管家告诉客人哪个是空闲的,能够进行通信,

读流的操作,一定是阻塞的,所以只需将用户的数据通过通道,存到buffer中,之后对buffer进行读取操作。实现,不关心谁的消息,   

selector是event

 

NIO特性new  io   1.4可非阻塞IO

java.nio包

管家、通道、缓存

解决BIO阻塞,

NIO工作流程

通过事件判断所有注册在channel上的 小姐姐(各种变化)channel有自己的变化,有相应的变化的事件

具体要去干什么,交给ThreadPool

why:

提高并发、节约成本

互联网的高并发请求:对外的web服务器,内部的为服务。

tomcat    由BIO----> 改成NIO

NIO使用

channel要注册到selector上

通过selector,一个线程能够处理多个channel,可以极大的减少线程的数量。使用CPU核心数量的线程,充分利用cpu资源,减少线程间的切换。

1、创建管家

2、将channel注册到selector上

3、selector.select()

4、获取SelectionKey

5、处理selectorKeys

 

selectionKey是一个对象。其中存着各种准备就绪的channel

对keys进行迭代,拿到具体的哪个channel

有四个事件,哪个事件做不同的事。针对不同的事件做不同是事。

flip方法                                                                              flip方法执行完之后,再去读数据就能够读了

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智达教育‍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值