Java 网络编程之NIO(Channel)

vins-mono前端详解(2)——imu预积分 本篇文章详细讲解了vins-mono中imu预积分内容,包括复杂的公式推导。 阅读详情

同步 VS 异步

      同步

       同步编程是指当程序执行某个操作时,它必须等待该操作完成才能继续执行下一个操作。这意味着程序在执行网络请求时必须等待网络请求完成才能继续执行下一步操作,因此同步编程通常会导致程序的性能降低。在网络编程中,同步编程通常用于处理较慢的网络请求,例如文件读写操作。

      异步

      异步编程是指将一个操作 (如网络请求) 放置在线程中,但并不阻塞该线程,而是在操作完成或者出现异常时再通知线程。这意味着线程可以在执行其他任务的同时处理网络请求,从而提高了程序的效率。在异步编程中,线程池可以帮助管理多个异步操作,从而避免线程的频繁创建和销毁。

      阻塞

      阻塞编程是指在处理网络请求时,如果网络请求无法完成,程序将无法继续执行其他操作,而是被迫等待网络请求完成。这意味着程序在执行网络请求时必须等待网络请求完成才能继续执行下一步操作,因此阻塞编程通常也会导致程序的性能降低。在网络编程中,阻塞编程通常用于处理固定的、快速的网络请求,例如 HTTP 请求。

     非阻塞

     非阻塞编程是指在处理网络请求时,等待网络请求完成之后再继续执行下一个操作,而不是在处理网络请求时阻塞线程。这可以提高程序的响应速度,但需要更多的内存和资源来支持长时间运行的网络请求。在非阻塞编程中,可以使用 poll、epoll 等事件驱动模型来管理网络请求。

    异步 VS 非阻塞

        异步编程和非阻塞编程的区别主要在于它们的执行方式。异步编程是将操作放置在线程中,但并不阻塞线程,而是在操作完成或者出现异常时再通知线程。非阻塞编程则是等待网络请求完成之后再继续执行下一个操作。因此,异步编程更加灵活,可以在处理网络请求的同时执行其他任务,而非阻塞编程则需要更多内存和资源来支持长时间运行的网络请求。

     同步 VS 阻塞

       同步和阻塞的区别主要在于它们的执行方式。同步编程必须等待操作完成才能继续执行下一个操作,而阻塞编程则是被迫等待操作完成才能继续执行下一个操作。因此,同步编程通常适用于处理较慢的网络请求,而阻塞编程通常适用于处理固定的、快速的网络请求。

                 举例说明(个人理解【如有错误请指出联系笔者感激不尽!!!!】)

比如我们把客人去饭店吃饭的事情举例

   【网络请求】 客人(最多) 【处理请求】服务员(中)【读写操作】 厨师(最少) 

    同步阻塞:   

        m个客人来到饭店,n个服务员对应n个客人,(m-n)客人等待【阻塞】服务员处理完自己负责的客人,当服务员把客人点的菜单交给厨师时,此时服务员不能离开,而且客人也不能干自己事情【同步】,等待厨师做完饭,服务员上完菜,这时客人可以做自己事情,服务员接着服务剩下的客人。

    同步非阻塞:

        m个客人来到饭店,n个服务员对应n个客人,但是此时服务员把客人点的菜单交给厨师的做菜队列中,接着服务剩下的(m-n)客人【非阻塞】。而且此时客人也不能干自己事情【同步】,等待厨师做完饭,通知服务员上完菜,这时客人可以做自己事情,服务员接着服务剩下的客人。

    异步阻塞(没有此情况)

    异步非阻塞(AIO):

     m个客人来到饭店,n个服务员对应n个客人,但是此时服务员把客人点的菜单交给厨师的做菜队列中,接着服务剩下的(m-n)客人【非阻塞】。点完菜的客人可以离开饭店做自己事情【异步】等待厨师做完饭,通知服务员上菜,服务员通知客人可以吃饭。

NIO的核心组成部分

       Channel

       可以翻译成“通道”。Channel和IO中的Stream(流)是差不多一个等级的。只不过Stream是单向的,譬如: InputStream, OutputStream.而Channel是双向的,既可以用来进行读操作,又可以用来进行写操作。

             FileChannel、DatagramChannel、 SocketChannel 和 ServerSocketChannel
                       IO                     UDP                                      TCP     

       Buffer       

ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,(对应)
     byte,               char,          double,             float     , int,            long,           short   

      Selector

        Selector 运行单线程处理多个 Channel,如果你的应用打开了多个通道,但每个连接
的流量都很低,使用 Selector 就会很方便。例如在一个聊天服务器中。要使用
Selector, 得向 Selector 注册 Channel,然后调用它的 select()方法。这个方法会一直
阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,
事件的例子有如新的连接进来、数据接收等。

FileChannel(只能工作在阻塞的状态下)

基本的读写操作

   public void readFile() throws Exception {
        RandomAccessFile file = new RandomAccessFile("D:\\code\\JVMCODE\\a.txt", "r");
        FileChannel channel = file.getChannel();
        ByteBuffer buf = ByteBuffer.allocate(10);
        buf.clear();//相当于清空缓存
        int len = 0;//记录读入
        while((len = channel.read(buf)) != -1){
              buf.flip();//读写指针指到缓存头部
              while(buf.hasRemaining()){
                  System.out.println((char) buf.get());
              }
            System.out.println("进入下一个读操作");
              buf.clear();
        }
        channel.close();
        file.close();
    }

    @Test
    public void writeFile() throws Exception{
        RandomAccessFile file = new RandomAccessFile("D:\\code\\JVMCODE\\a.txt", "rw");
        FileChannel channel = file.getChannel();
        ByteBuffer buf = ByteBuffer.allocate(40);
        buf.clear();//相当于清空缓存
        buf.put("你好世界".getBytes());
        buf.flip();//读写指针指到缓存头部
        while (buf.hasRemaining()){
            channel.write(buf);
            System.out.println("进行下一次的写操作");
        }
        channel.close();
        file.close();
    }

FileChannel的常用方法

方法描述
int read(ByteBuffer dst)从Channel中读取数据到ByteBuffer
int read(ByteBufer[] dsts)将Channel中的数据“分散”到ByteBuffer[]
int write(ByteBuffer src)将ByteBuffer 中的数据写入Channel
long write(ByteBuffer[] srcs)将ByteBuffer[] 中的数据“聚集”到Channel
long position()返回此通道的文件位置
FileChannel position(long p)设置此通道的文件位置
long size()返回此通道的文件的当前大小
FileChannel truncate(long s)将此通道的文件截取为给定大小
void force(boolean metaData)强制将所有对此通道的文件更新写入到存储设备中
transferTo(初始位,长度,目的通道)
将数据从 FileChannel 传输到其他的 channel 中
transferFrom(原通道,初始位,长度)
将FileChannel数据从源通道传输到 FileChannel 中

SocketChannel

1SocketChannel 就是 NIO 对于非阻塞 socket 操作的支持的组件,其在 socket 上 封装了一层,主要是支持了非阻塞的读写。同时改进了传统的单向流 API,Channel 同时支持读写。
2)socket 通道类主要分为 DatagramChannel、SocketChannel 和 ServerSocketChannel,它们在被实例化时都会创建一个对等 socket 对象。要把一个 socket 通道置于非阻塞模式,我们要依靠所有 socket 通道类的公有超级类: SelectableChannel。就绪选择(readiness selection)是一种可以用来查询通道的 机制,该查询可以判断通道是否准备好执行一个目标操作,如读或写。非阻塞 I/O 和 可选择性是紧密相连的,那也正是管理阻塞模式的 API 代码要在 SelectableChannel
超级类中定义的原因。
3)设置或重新设置一个通道的阻塞模式是很简单的,只要调用 configureBlocking( )方法即可,传递参数值为 true 则设为阻塞模式,参数值为 false 值设为非阻塞模式。可以通过调用 isBlocking( )方法来判断某个 socket 通道当前处哪种模式。

SocketChannel

                     Java NIO 中的 SocketChannel 是一个连接到 TCP 网络套接字的通道。
SocketChannel 是一种面向流连接 sockets 套接字的可选择通道。从这里可以看出:
        SocketChannel 是用来连接 Socket 套接字
        SocketChannel 主要用途用来处理网络 I/O 的通道
        SocketChannel 是基于 TCP 连接传输
        SocketChannel 实现了可选择通道,可以被多路复用的
1)对于已经存在的 socket 不能创建 SocketChannel
2)SocketChannel 中提供的 open 接口创建的 Channel 并没有进行网络级联,需要使
用 connect 接口连接到指定地址
3)未进行连接的 SocketChannle 执行 I/O 操作时,会抛出
NotYetConnectedException
4)SocketChannel 支持两种 I/O 模式:阻塞式和非阻塞式
5)SocketChannel 支持异步关闭。如果 SocketChannel 在一个线程上 read 阻塞,另
一个线程对该 SocketChannel 调用 shutdownInput,则读阻塞的线程将返回-1 表示没有
读取任何数据;如果 SocketChannel 在一个线程上 write 阻塞,另一个线程对该
SocketChannel 调用 shutdownWrite,则写阻塞的线程将抛出
AsynchronousCloseException
6)SocketChannel 支持设定参数
        SO_SNDBUF                 套接字发送缓冲区大小
        SO_RCVBUF                 套接字接收缓冲区大小
        SO_KEEPALIVE             保活连接
        O_REUSEADDR            复用地址
        SO_LINGER                   有数据传输时延缓关闭 Channel (只有在非阻塞模式下有用)
        TCP_NODELAY              禁用 Nagle 算法

使用的步骤

 【1】 创建SocketChannel   

 public void createSocketChannel() throws Exception {
        //方式一:使用SocketChannel的静态方法open(套接字)【推荐使用】
        SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        //方式二:使用功connect
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("www.baidu.com",80));
    }

【2】连接检验

  public void isConnect() throws Exception{
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        System.out.println(socketChannel.isOpen());//测试是否为open状态
        System.out.println(socketChannel.isConnected());//测试是否为已经被连接
        System.out.println(socketChannel.isConnectionPending());//测试是正在被连接
        System.out.println(socketChannel.finishConnect());//是否已经完成连接
    }

【3】读写模式(是否为阻塞或者非阻塞)

  @Test
    public void isBlocking() throws Exception{
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        System.out.println(socketChannel.isBlocking());
        socketChannel.configureBlocking(false);//设置非阻塞
        System.out.println(socketChannel.isBlocking());
    }

【4】读写

阻塞读写

@Test
    public void read1() throws Exception{
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        ByteBuffer buf = ByteBuffer.allocate(1024);
        socketChannel.read(buf);//线程被阻塞因为百度不为发给你消息
        socketChannel.close();
        System.out.println("read over");//不会打印
    }

非阻塞读写

@Test
    public void read2() throws Exception{
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        ByteBuffer buf = ByteBuffer.allocate(1024);
        socketChannel.configureBlocking(false);//设置非阻塞
        socketChannel.read(buf);
        socketChannel.close();
        System.out.println("read over");//会打印
    }

 【5】设置参数

 @Test
    public void set() throws Exception{
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));
        socketChannel.setOption(StandardSocketOptions.TCP_NODELAY,Boolean.TRUE);
        System.out.println(socketChannel.getOption(StandardSocketOptions.TCP_NODELAY));
    }

ServerSocketChannel

ServerSocketChannel 是一个基于通道的 socket 监听器。它同我们所熟悉的
java.net.ServerSocket 执行相同的任务,不过它增加了通道语义,因此能够在非阻塞
模式下运行。
由于 ServerSocketChannel 没有 bind()方法,因此有必要取出对等的 socket 并使用
它来绑定到一个端口以开始监听连接。我们也是使用对等 ServerSocket 的 API 来根
据需要设置其他的 socket 选项。
同 java.net.ServerSocket 一样,ServerSocketChannel 也有 accept( )方法。
ServerSocketChannel 的 accept()方法会返回 SocketChannel 类型对象,
SocketChannel 可以在非阻塞模式下运行。

非阻塞的accpet()方法

@Test
    public void notBlockAccept() throws Exception{
        ByteBuffer buf = ByteBuffer.allocate(48);
        buf.clear();
        buf.put("hello".getBytes());
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(1234));
        ssc.configureBlocking(false);
        while (true){
            System.out.println("等待连接!");
            SocketChannel accept = ssc.accept();
            if(accept == null){
                System.out.println("null connect");
                Thread.sleep(1000);
            }else {
                System.out.println("建立连接:"+accept.getRemoteAddress());
                buf.rewind();
                /*
                 Buffer.rewind() 方法用于将字符缓冲区恢复到最初的状态,
                 即缓冲区中的数据没有被读取或写入。
                 */
                accept.write(buf);//获取hello值
                accept.close();
            }
        }
    }

【1】打开ServerSocketChannel

 @Test
    public void open() throws Exception {
        ServerSocketChannel ssc = ServerSocketChannel.open();
    }

【2】监听新的链接

    通过 ServerSocketChannel.accept() 方法监听新进的连接。当 accept()方法返回时
候,它返回一个包含新进来的连接的 SocketChannel。因此, accept()方法会一直阻塞
到有新连接到达。
   @Test
    public void accept() throws Exception{
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(1222));
        while (true){
            System.out.println("等待连接");
            SocketChannel accept = ssc.accept();
        }
    }
}

                                                    只会执行一次因为这是阻塞的

DatagramChannel

每 一个 DatagramChannel 对象也有一个关联的 DatagramSocket 对象。正如
SocketChannel 模拟连接导向的流协议(如 TCP/IP),DatagramChannel 则模拟包
导向的无连接协议(如 UDP/IP)。DatagramChannel 是无连接的,每个数据报
(datagram)都是一个自包含的实体,拥有它自己的目的地址及不依赖其他数据报的
数据负载。与面向流的的 socket 不同,DatagramChannel 可以发送单独的数据报给
不同的目的地址。同样,DatagramChannel 对象也可以接收来自任意地址的数据包
每个到达的数据报都含有关于它来自何处的信息(源地址)
【1】打开DatagramChannel
 @Test
    public void open() throws Exception{
        DatagramChannel server = DatagramChannel.open();
        server.socket().bind(new InetSocketAddress(1243));
    }

【2】链接

        UDP 不存在真正意义上的连接,这里的连接是向特定服务地址用 read 和 write 接收
  发送数据包。
client.connect(new InetSocketAddress("127.0.0.1",10086));
int readSize= client.read(sendBuffer);
server.write(sendBuffer);
               read()和 write()只有在 connect()后才能使用,不然会抛
                NotYetConnectedException 异常。用 read()接收时,如果没有接收到包,会抛
                 PortUnreachableException 异常。

【3】接收数据  recevice()接收UDP包

    @Test
    public void reviceUDP() throws Exception{
        DatagramChannel server = DatagramChannel.open();
        server.socket().bind(new InetSocketAddress(1243));
        server.configureBlocking(false);
        ByteBuffer receviceBuffer = ByteBuffer.allocate(34);
        receviceBuffer.clear();
        SocketAddress receive = server.receive(receviceBuffer);
        System.out.println(receive);
       // SocketAddress 可以获得发包的 ip、端口等信息,用 toString 查看,格式如下
    }

【4】发送数据  send()发送UDP包

@Test
    public void sendUDP() throws Exception {
        DatagramChannel server = DatagramChannel.open();
        ByteBuffer buf = ByteBuffer.wrap("hello".getBytes());
        server.send(buf, new InetSocketAddress("127.0.0.1", 1003));
    }

综合案列

 /**
     * 收包端
     */
    @Test
    public void receive() throws Exception {
        DatagramChannel receiveChannel= DatagramChannel.open();
        InetSocketAddress receiveAddress= new InetSocketAddress(9999);
        receiveChannel.bind(receiveAddress);
        ByteBuffer receiveBuffer= ByteBuffer.allocate(512);
        while (true) {
            receiveBuffer.clear();
            SocketAddress sendAddress= receiveChannel.receive(receiveBuffer);
            receiveBuffer.flip();
            System.out.print(sendAddress.toString() + " ");
            System.out.println(Charset.forName("UTF-8").decode(receiveBuffer));
        }
    }
    /**
     * 只接收和发送 9999 的数据包
     */
    @Test
    public void testConect1() throws Exception {
        DatagramChannel connChannel= DatagramChannel.open();
        connChannel.bind(new InetSocketAddress(9998));
        connChannel.connect(new InetSocketAddress("127.0.0.1",9999));
        connChannel.write(ByteBuffer.wrap("发包".getBytes("UTF-8")));
        ByteBuffer readBuffer= ByteBuffer.allocate(512);
        while (true) {
            try {
                readBuffer.clear();
                connChannel.read(readBuffer);
                readBuffer.flip();
                System.out.println(Charset.forName("UTF-8").decode(readBuffer));
            }catch(Exception e) {
            }
        }
    }

C# 实现 Modbus 通信全教程(支持 TCP RTU,含完整错误处理) 环境准备:安装 NModbus4 库,明确设备参数(IP/串口、地址、数据类型);连接设备:TCP 用 TcpClient,RTU 用 SerialPort,注意超时参数匹配;读写数据:根据数据类型调用对应方法(读保持寄存器用 ReadHoldingRegisters);错误处理:捕获连接、超时、协议等异常,针对性排查问题。掌握这些后,即可轻松实现与工业设备的 Modbus 通信,为上位机开发提供稳定的数据交互能力。 阅读详情

相关推荐

JAVA实现远程文件读取

JAVA实现远程文件读取

Java网络编程——NIO编程

JavaNIO全称javanon-blockingIO,是指JDK提供的新API。从JDK1.4开始,Java提供了一系列改进的输入/输出的新特性,被统称为NIO(即NewIO),是同步非阻塞的.缓冲区(Buffer)缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个数组,该对象提供了一组方法,可以更轻松地使用内存块,缓冲区对象内置了一些机制,能够跟踪记录缓冲区的状态变化情况。Channel提供从网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer.......

weixin_62017112的博客 2266

谷歌浏览器离线包ChromeStandaloneSetup64.exe

畅享全方位的快速体验用户每次上网,一般都有一定的目的。无论这目的是大是小,是工作还是娱乐,Chrome 所具备的智能工具非凡速度都能让您在网络世界得心应手地操作、创作探索。

javaNIO编程

java NIO详解

敲代码的小小酥的博客 1950

java网络编程——NIO架构

简单叙述java NIO架构,并基于NIO架构下实现聊天系统的代码编写

tang_seven的博客 2988

java网络编程NIO

Java NIO (New IO 或Non Blocking IO) 是从java1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO支持面向缓存区的,基于通信的IO操作。NIO将以更加高效的方式进行文件的读写操作。java NIO 由以下几个核心部分组成ChannelsBuffersSelectors虽然java NIO 中除此之外还有很多类组件,但Channel,BufferSelector构成了核心的API。

m0_57605288的博客 261

javaNIO

javaNIO

weixin_44353972的博客 349

Java网络编程(三):NIO核心组件Channel通道详解

Java网络编程(三):NIO核心组件Channel通道详解

Yeats_Liao的博客 6525

java--NIO详解--Buffer、channel网络编程

目录一、buffer--缓冲区的基本使用1.核心与基础用法2.实现字符集转换二、Channel的基本使用三、socketChannel网络编程--阻塞式四、socketChannel网络编程--非阻塞式1.Client客户端类2.Server服务端 一、buffer–缓冲区的基本使用 1.核心与基础用法 初始化缓冲区:XXXBuffer.allocate(int capacity) 数据加入缓冲区:buffer.put(byte[] data) 切换为读模式:byteBuffer.flip() 读取缓冲区

lzq00277的博客 1387

Java网络编程NIO详解4:浅析NIO包中的Buffer、Channel Selector

本文转载自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how2playlife.com 本文是微信公众号【Java技术江湖】的《不可轻视的Java网络编程》其中一篇,本文部分内容来源于...

AliCoder的博客 439

Java中JDK必知必会的NIO网络编程、BIO、NIO、AIO、同步异步,阻塞非阻塞、NIO的三大核心组件、Selector、Channel、Buffer,单线程、多线程、主从Reactor模型】

Java中JDK必知必会的NIO网络编程、三种必会的网络IO模型、BIO、NIO、AIO、JDK中的NIO网络编程、为什么不建议使用BIO?同步与异步,阻塞与非阻塞、NIO的三大核心组件,Selector选择器,channel通道、buffer缓冲区、案例实战代码、NIO网络编程中一些重要的类、常用的属性以及常用的方法、直接内存、堆上内存、单线程Reactor模型,多线程Reactor模型、主从Reactor模型?为什么使用Netty,不用传统的NIO编程】

Coder_ljw的博客 517

Java网络编程——NIO三大组件Buffer、Channel、Selector

Java NIOJava Non-Blocking IO)也就是非阻塞IO,说是非阻塞IO,其实NIO也支持阻塞IO模型(默认就是),相对于BIO来说,NIO最大的特点是支持IO多路复用模式,可以通过一个线程监控多个IO流(Socket)的状态,来同时管理多个客户端,极大提高了服务器的吞吐能力。在NIO中有3个比较重要的组件:Buffer、Channel、Selector。......

点滴汇聚,智在积累。——Danny 1720

Java网络编程(6)NIO - Channel详解

前言 NIO的三个核心组件:Buffer、Channel、Selector Java网络编程(4)NIO的理解与NIO的三个组件完成了大概的了解 Java网络编程(5)NIO - Buffer详解详细了解了Buffer 现在开始详细的学习Channel 目录 Channel概念 Channel类继承结构 FileChannel 3.1. 常用方法 3.2. 案例 分散读取与聚集写入 通道复制数据...

key_768的博客 513

Java NIO 三大核心(Buffer、Channel、Selector)理解

NIO 三大核心(Buffer、Channel、Selector)

在路上 1075

javaNIO入门学习介绍及NIO网络编程Demo

Java1.4开始就有了NIO,随着程序对性能的要求越来越高,NIO得到了广泛使用。 IO NIO 面向流 面向缓冲区 阻塞 非阻塞 / 有选择器

qq_42401622的博客 484

Java NIO系列教程(十) Java NIO DatagramChannel

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34318326的博客 314

Java NIO详解:深入理解非阻塞式网络编程

Java NIO(New I/O)是一种高性能的I/O处理机制,它提供了对标准Java I/O API的替代方案,以支持更高效的文件网络数据传输。本文将从NIO的基本概念、核心组件、关键特性以及实际应用等方面进行全面深入的解析,帮助读者理解并掌握这一强大工具。

suqieer的博客 2041

Java NIO 模型代码示例

在高并发(持续大量的连接同时请求)场景中,之前的两种 BIO 优化方案都需要消耗大量的线程来维持连接。并且 CPU 在线程切换上消耗很大。 Java NIO 模型的主要优势:少量的线程就可以处理大量连接的请求。 主要组成: Channel 通道:IO 传输发生时数据通过的入口 Buffer 缓冲区:可以理解为数据在管道传输时的起点终点 Selector 选取器(IO监听器):负责监听 IO 事件 所用通道都向 Selector 注册,Selector 负责轮询检测,然后服务端进程会阻塞在 Select

qq_33471737的博客 2107

JavaNIO代码篇

传统的I/O: 传统的服务器的I/O是阻塞的,即当服务器端开启后,它会监听端口,直到有客户端发来请求,否则一直将是堵塞的, NIO(非阻塞I/O): 基础概念: 通道:用于建立客户端服务端的连接,可以将输入/输出流写入到通道,通道将缓冲区的数据块移入或移出到各种I/O源,如文件,socket,数据报。对于网络编程,只有三类通道类:SocketChannel,ServerSocketCha...

ld3205的博客 928

Java中的OIONIO详解(含代码)

阻塞 vs 非阻塞:OIO是阻塞I/O模型,每个I/O操作都是阻塞的,即线程在执行I/O操作时会一直等待直到操作完成。NIO是非阻塞I/O模型,它使用Selector来实现非阻塞操作,允许单个线程处理多个通道的I/O事件。多线程 vs 单线程:OIO模型中,每个连接都需要创建一个独立的线程进行处理,当连接数量较多时,线程开销较大。NIO模型中,可以使用单个线程处理多个连接,减少了线程开销。

一叶知秋 3406
上一篇: 工厂模式(简单工厂 工厂方法 抽象工厂)
下一篇: Linux VIM编辑器常用指令
百事yyds
博客等级 码龄5年 8粉丝 73原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值