IO(BIO) 和NIO 的区别:其本质就是阻塞和非阻塞的区别

 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,那么程序就一直等着,直到传输完毕为止。

 非阻塞概念:应用程序直接可以获取已经准备就绪好的数,无需等待。(会将数据放在缓存区,加载完后 会给客户端发送一个信号,客户端会读取数据)

IO为同步阻塞模式,NIO为同步非阻塞模式,NIO并没有实现异步,而JDK1.7以后AIO 支持异步。

同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪;或者采用轮询的策略实时检查数据的就绪状态,如果就绪则获取数据

异步时,则所有的IO读写操作交给操作系统处理,与我们的应用程序没有直接关系,我们程序不需要关系IO读写,当操作系统完成IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据即可。




java.io 最为核心的一个概念就是流,面向流的编程。在java中,一个流要么是输入流,要么是输出流,不可能同时既是输入流又是输出流。

Java.nio 中拥有3个核心概念:Selector ,Channel与Buffer。在java.nio中,我们是面向块或是缓冲区编程的。Buffer本身就是一块内存,底层实现上,就是个数组,数据的读写都是通过Buffer来实现的。

除了数组之外,Buffer还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程。

java中的8中原生数据类型都有各自的Buffer类型,如IntBuffer,LongBuffer等等

Channel指的是可以向其写入数据或者是从中读取数据的对象,它类似于java.io中的Stream。

所有的数据的读写都是通过Buffer来进行的,永远不会出现直接向Channel写入数据的情况,或者从Channel读取数据的情况。

与Stream不同的是,Channel是双向的,一个流只可能是InputStream或者OutputStream,Channel大开后则可以进行读取 写入。

由于Channel是双向的,因此它能更好的反应出底层操作系统的真实情况,在Linux系统中,底层操作系统的通道就是双向的。

通道Channel,它就像自来水管道一样,网络数据通过channle读取和写入,通道与流不同之处在于通道是双向的,而流只是一个方向上移动的,而通道可以读写二者同时进行,最关键的是可以与多路复用器结合起来,有多种的状态位,方便多路复用器去识别。

通道分为两类 : 一类是网络读写的 SelectableChannel 一类事用于文件操作的FileChannel 我们使用SocketChannel和ServerSocketChannel都是SelectableChannel的子类



java Queue非阻塞 java nio阻塞和非阻塞_数据

下面来个简单的栗子:


package nio;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NioTest {

    public static void main(String[] args) throws IOException{
        FileInputStream fileInputStream = new FileInputStream("Niotest.txt");
        FileChannel fileChannel =fileInputStream.getChannel();


        ByteBuffer byteBuffer = ByteBuffer.allocate(512);
        fileChannel.read(byteBuffer);

        byteBuffer.flip();

        while(byteBuffer.remaining()>0){
           byte b = byteBuffer.get();
           System.out.println("---:"+(char)b);
        }

        fileInputStream.close();


    }
}





package nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NioTest3 {
    public static void main(String[] args)  throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("Niotest3.txt");

        FileChannel fileChannel =fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(512);

        byte[] mess = " hello wrold welcome , nihao".getBytes();

        for (int i = 0; i< mess.length;i++){
            byteBuffer.put(mess[i]);
        }

        byteBuffer.flip();
        fileChannel.write(byteBuffer);
        fileOutputStream.close();




    }
}




package nio;

import java.nio.IntBuffer;
import java.util.Random;

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

        IntBuffer intBuffer = IntBuffer.allocate(10);

        for (int i = 0; i <intBuffer.capacity() ; i++) {
            int rand = new Random().nextInt(20);
            intBuffer.put(rand);
        }

        intBuffer.flip();

        while (intBuffer.hasRemaining()){
            System.out.println(intBuffer.get());
        }

    }
}