JAVA NIO(死磕1)

【正文】JAVA NIO 死磕1: 

JAVA NIO简介

1. JAVA NIO简介

Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO。由于之前老的I/O类库是阻塞I/O,New I/O类库的目标就是要让Java支持非阻塞I/O,所以,更多的人喜欢称之为非阻塞I/O(Non-block I/O)。

NIO弥补了原来同步阻塞I/O的不足,它在标准Java代码中提供了高速的、面向块的I/O。

Java NIO 由以下几个核心部分组成:

Channel

Buffer

Selector

1.1. NIO 和 OIO 的对比

旧的IO(OIO) 和 NIO 的区别主要体现在三个方面:

(1)OIO 基于流(Stream oriented),而 NIO 基于 Buffer (Buffer oriented);

(2)OIO 操作是阻塞的,而 NIO 操作是非阻塞的;

(3)OIO 没有 selector 概念,而 NIO 有 selector 概念.

旧的IO(OIO) 是面向字节流或字符流的,在一般的OIO操作中,我们以流式的方式顺序地从一个 Stream 中读取一个或多个字节,因此,我们也就不能随意改变读取指针的位置。

而在 NIO 中,而是引入了 Channel 和 Buffer 的概念。在 NIO 中,只需要从 Channel 中读取数据到 Buffer 中,或将数据从 Buffer 中写入到 Channel。并且,不像OIO 那样是顺序操作,在NIO 中,我们可以随意地读取任意位置的数据.

1.2. 阻塞和非阻塞

在OIO中,Java 提供的各种 stream 流操作都是阻塞的,例如我们调用一个 read 方法读取一个文件的内容,那么调用 read 的线程会被阻塞住,直到 read 操作完成。

而 NIO 的非阻塞模式允许我们非阻塞地进行 IO 操作。 例如我们需要从网络中读取数据。在 NIO 的非阻塞模式中,当我们调用 read 方法时,如果此时有数据,则 read 读取并返回; 如果此时没有数据,则 read 直接返回,而不会阻塞当前线程。

NIO的非阻塞,是如何做到的呢?

使用的是通道和通道的多路复用技术。先来看通道Channel。

1.3. Channel

OIO中,通常来说,一个连接使用有两个流,一个输入流一个输出流。通过两个流不断的进行输入和输出。

与之相对应,NIO中,通常来说,一个连接就是一个通道Channel表示,所有的 NIO 的 I/O 操作都是从 Channel 开始的。 一个 channel 类似于OIO中的两个 stream的结合体。

1.4. selector

通道Channel要进行多路复用,基础就是选择器selector。

Selector是何方神圣?

这是一个IO事件的查询器,通过 Selector,一个线程可以查询多个 Channel 的 IO 事件的就绪状态。

我们要做的工作,就是将要进行状态查询的Channel(相当于流)注册到选择器Seletor中。当我们向一个 Selector 中注册了 Channel 后,Selector 内部的机制就可以自动地为我们不断地查询(select) 这些注册的 Channel 是否有已就绪的 IO 事件(例如可读,可写,网络连接完成等)。

通过这样的 Selector 机制,我们就可以很简单地使用一个线程高效地管理多个 Channel 了。

1.5. Java NIO Buffer

当我们需要与 NIO Channel 进行交互时,我们就需要使用到 NIO Buffer,即数据从 Buffer读取到 Channel 中,并且从 Channel 中写入到 Buffer 中。

Buffer的使用,也是NIO非阻塞的重要的前提和基础之一。

下面结合实例和源码实例,开启JAVA NIO的死磕之路。次序从Buffer,然后到Channel,最后讲最复杂的 Selector多路复用器。

源码:

代码工程:  JavaNioDemo.zip

下载地址:在疯狂创客圈QQ群文件共享。

疯狂创客圈:如果说Java是一个武林,这里的聚集一群武痴, 交流编程体验心得
QQ群链接:疯狂创客圈QQ群

无编程不创客,无案例不学习。 一定记得去跑一跑案例哦

JAVA NIO 死磕全目录

原文地址:https://www.cnblogs.com/crazymakercircle/p/9826759.html

时间: 2024-11-06 11:43:44

JAVA NIO(死磕1)的相关文章

疯狂创客圈 JAVA死磕系列 总目录

无编程不创客,无案例不学习.疯狂创客圈,一大波高手正在交流.学习中! 疯狂创客圈 Java 死磕系列: [CSDN 总入口] [博客园 总入口] JAVA NIO  死磕系列:NIO简介.NIO  Buffer. NIO channel. NIO Selector reactor 模式 死磕系列: Reactor模式 Netty 源码 死磕系列: 环境搭建 .  EventLoop. ChannelHandler . Pipeline模式.Pipeline inbound. Pipeline o

Reactor(死磕2)

[正文]netty源码  死磕2:  传说中神一样的Reactor反应器模式 本文目录 1. 为什么是Reactor模式 2. Reactor模式简介 3. 多线程IO的致命缺陷 4. 单线程Reactor模型 4.1. 什么是单线程Reactor呢? 4.2. 单线程Reactor的参考代码 4.3. 单线程模式的缺点: 5. 多线程的Reactor 5.1. 基于线程池的改进 5.2. 改进后的完整示意图 5.3. 多线程Reactor的参考代码 6. Reactor持续改进 7. Reac

【死磕Java并发】-----J.U.C之重入锁:ReentrantLock

此篇博客所有源码均来自JDK 1.8 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制.它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大.灵活的锁机制,可以减少死锁发生的概率. API介绍如下: 一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大.ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥

【死磕Java并发】-----Java内存模型之分析volatile

前篇博客[死磕Java并发]-–深入分析volatile的实现原理 中已经阐述了volatile的特性了: volatile可见性:对一个volatile的读,总可以看到对这个变量最终的写: volatile原子性:volatile对单个读/写具有原子性(32位Long.Double),但是复合操作除外,例如i++; JVM底层采用"内存屏障"来实现volatile语义 下面LZ就通过happens-before原则和volatile的内存语义两个方向介绍volatile. volat

【死磕Java并发】-----J.U.C之AQS:CLH同步队列

此篇博客所有源码均来自JDK 1.8 在上篇博客[死磕Java并发]-–J.U.C之AQS:AQS简介中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个FIFO双向队列,AQS依赖它来完成同步状态的管理,当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态. 在CLH同步队列中,一个节点表示一个线程

【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock

此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低.所以就提供了读写锁. 读写锁维护着一对锁,一个读锁和一个写锁.通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:在同一时间可以允许多个读线程同时访问,但是在写线程访问时,所有读线程和写线程都会被阻塞. 读写锁的主要特

Java类加载器( CLassLoader ) 死磕 3: 揭秘 ClassLoader抽象基类

[正文]Java类加载器(  CLassLoader ) 死磕3:  揭秘 ClassLoader抽象基类 3.1. 揭秘ClassLoader抽象基类 3.1.1. 类的加载分类:隐式加载和显示加载 java中类是动态加载的,jvm启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载.一是加快启动的速度,二是节约内存.如果一次性加载全部jar包的所有class,速度会很慢. 动态载入一个class类,有两种方式: (1) implicit隐式加载 即通过实例化才载入的特性来

【正文】Java类加载器( CLassLoader ) 死磕 4: 神秘的双亲委托机制

[正文]Java类加载器(  CLassLoader ) 死磕4:  神秘的双亲委托机制 本小节目录 4.1. 每个类加载器都有一个parent父加载器 4.2. 类加载器之间的层次关系 4.3. 类的加载次序 4.4 双亲委托机制原理与沙箱机制 4.5. forName方法和loadClass方法的关系 4.6. 使用组合而不用继承 4.7. 各种不同的类加载途径 4.1.每个类加载器都有一个parent父加载器 每个类加载器都有一个parent父加载器,比如加载SystemConfig.cl

死磕 java集合之ConcurrentHashMap源码分析(三)

本章接着上两章,链接直达: 死磕 java集合之ConcurrentHashMap源码分析(一) 死磕 java集合之ConcurrentHashMap源码分析(二) 删除元素 删除元素跟添加元素一样,都是先找到元素所在的桶,然后采用分段锁的思想锁住整个桶,再进行操作. public V remove(Object key) { // 调用替换节点方法 return replaceNode(key, null, null); } final V replaceNode(Object key, V