一分钟带你彻底理解同步异步,阻塞非阻塞的区别

同步异步&阻塞非阻塞区别

  • 1. 同步&异步
  • 2. 阻塞&非阻塞
  • 3. 几种IO分类
    • 3.1. 同步阻塞IO
    • 3.2. 同步非阻塞IO
    • 3.3. IO多路复用(Reactor模式)
    • 3.4. 异步IO(Proactor模式)

1. 同步&异步

同步与异步:关心的是消息通知机制

如果调用方发起调用后,需要等待这个返回值,调用方主动去等它的返回,那么就是同步

如果调用方发起调用后,不用调用方去主动等它返回或者主动询问它返回,那么就是异步

下面简单列举几个例子

同步

A a = read();

异步

read(()->{
    public void onSuccess(){
        xxxx
    }
})

思考:Future算异步还是同步?

Future future = ThreadPoolExecutor.submit(new Task());
int result = future.get();

2. 阻塞&非阻塞

阻塞&非阻塞:关心的是调用者的状态

阻塞:调用者发起调用后,调用者从运行态(Runnable)进入到阻塞态(Blocked),直到返回值准备好返回才切换会运行态

非阻塞:调用者发起调用后,不会进入阻塞态(Blocked),会立刻返回,返回值可以是空值,也可以是其他;应用程序需要自己轮训返回值是否准备好

下面也举几个例子

阻塞

// 如果文件没有读取完毕会一直阻塞
File file = read();

非阻塞

while(true){
     data = read();
     if(data!= error){
         处理数据
         break;
     }
}

思考:Java NIO,下面那些方式是非阻塞的?
PS:代码简单写了下,可能不完全正确,主要是体现场景的意思

// 文件
FileChannel channel = FileChannel.getChannel();
ByteBuffer buff = ByteBuffer.allocate(256);
fcin.read(buff);
 
// 网络
SocketChannel channel = SocketChannel.open();
ByteBuffer buff = ByteBuffer.allocate(256);
fcin.read(buff);
 
// 网络
SocketChannel socketChannel = SocketChannel.open();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (selector.select() > 0) {
    Iterator iterator = selector.selectedKeys().iterator();
    SelectionKey selectionKey = iterator.next();
    if (selectionKey.isReadable()) {
         int readBytes = channel.read(responseBuffer); 
    }
}

3. 几种IO分类

3.1. 同步阻塞IO

Java BIO,也就是最原始的IO

Java NIO (非网络传输使用)

3.2. 同步非阻塞IO

Java NIO(网络传输使用)

Linux 下以O_NONBLOCK打开fd,然后执行read,write方法

3.3. IO多路复用(Reactor模式)

select

poll

epoll

Java NIO(selector器,底层依赖操作系统实现,Linux下是epoll)

3.4. 异步IO(Proactor模式)

Windows下的IOCP

Linux下的aio

IO只会有上面4种IO模型:同步阻塞,同步非阻塞,多路复用,异步IO

存在两种设计模式:Reactor模式和Proactor模式

你可能感兴趣的:(Java,操作系统)