一 . 什么是线层阻塞?

线程阻塞即线程高风亮节让出或放弃CPU,暂停执行,只有等到导致阻塞的原因解除,才能恢复运行;或者被其他线程中断,该线程会退出阻塞状态,并且抛出InterrutedException.

 

 

二 .常见的导致线程阻塞的原因:

      Ø线程执行了Thread.sleep(intn)方法,线程放弃CPU,睡眠n毫秒,然后恢复运行。但是此时被该线程所控制的同步代码块的锁定释放权利依然属于该线程,其他线程依然不能访问该代码块。

      Ø线程要执行一段同步代码,由于无法获得相关的同步锁,只好进入阻塞状态,等到获得了同步锁才能恢复运行。

      Ø线程执行了一个对象的wait()方法,进入阻塞状态,只有等到其他线程执行了该对象的notify()或notifyAll()方法,才可将其唤醒。

      Ø线程执行I/O操作或进行远程通信时,会因为等待相关的资源而进入阻塞状态。例如,当线程执行System.in.read()方法时,如果用户没有向控制台输入数据,则该线程会一直等到了用户的输入数据才才read()方法返回。

 

 

三 .什么是非阻塞

      所谓非阻塞,就是指当线程执行某些方法时,如果操作还没有就绪,就立即返回,而不会一直等到操作就绪。

 

四 .什么是阻塞I/O和非阻塞I/O

      可能出现阻塞的输入和输出操作被称为阻塞I/O;于此对照,如果执行输入和输出操作时,不会发生阻塞,则称为非阻塞I/O。

 

五 .Java.nio包提供了支持非阻塞通信的类

· ServerSocketChannel:ServerSocket的替代类,支持阻塞通信和非阻塞通信。

· SocketChannel: Socket的替代类,支持阻塞通信和非阻塞通信。

· Selector: 为ServerSocketChannel监控连接就绪事件,为SocketChannel监控连接就绪,读就绪和写就绪事件。

· SelectionKey: 代表ServerSocketChannel及SocketChannel注册事件的句柄。当一个SelectionKey对象位于Selector对象的selector-keys集合中时,就表示与这个SeletionKey对象相关的事件发生了。

· Charset类:代表字符编码,它提供了把字节流转换为字符串(解码过程)

和把字符串转换为字节流(编码过程)的使用方法。

 

· Buffer: 数据输入和输出往往是比较耗时的操作。缓冲区从两个方面提高I/O操作的效率:

           §减少实际的物理读写次数;

           §缓冲区在创建时被分配内存,这块内存区域一直被重用,这可以减少动态分配和回收内存区域的次数,可以通过修改缓冲区的极限属性来达到缓冲区重用的目的;

·缓冲区提供了三个属性来控制缓冲区的使用:容量,极限和位置,详细介绍参考java API文档;于此同时缓冲区还提供了用于改变以上3个属性的方法

           Ø clear(): 把极限设置为容量的值,再把位置设为0

           Ø flip(): 把极限设置为位置的值,再把位置设为0

           Ø rewind():不改变极限的值,把位置设为0

其中,flip()方法为从Buffer中取数据做好了准备,而clear()则向Buffer中装入数据做好准备。

有关缓冲区的更加详细的介绍请参考java API文档。

·通道Channel用来连接缓冲区与数据源或数据汇(数据目的地)

通道创建时被打开,一旦关闭通道,就不能重新打开了

     

数据源

通道

缓冲区

通道

数据汇

        

          

 

·高级通道操作:提供了分散读取和集中写数据的类和相关方法,可以进一步的提高输入和输出操作的速度,详述请参考java API文档。

 

 

§具有自动增长的缓冲区的ChannelIO类

      ChannelIO对SocketChannel进行了包装,增加了自动增长缓冲区容量的功能。当调用socketChannel.read(ByteBuffer buffer)方法时,如果buffer已满(position=limit)那么即使通道中还有未接收的数据,read方法也不会读取任何数据,二是直接返回0,表示读到了0个字节。

      为了能读取通道中的所有数据,必须保证缓冲区的容量足够大。在ChannelIO类中,有一个requestBuffer变量,它用来存放客户的HTTP请求数据,当requestBuffer剩余容量已经不足5%,并且还有HTTP请求数据未接收时,ChannelIO会自动扩充requestBuffer的容量,该功能由resizeRequestBuffer()方法完成。

      如下所示是ChannelIO类的源程序,它的read()和write()方法利用SocketChannel来接收和发送数据,并且它还提供了实用方法transferTo(),该方法能把文件中的数据发送到SockChannel中

 

 

 

 

      //此处省略import语句

      Public class ChannelIO{

           Protected SocketChannelsocketChannel;

           //存放请求数据

           Protected ByteBuffer requestBuffer;

           Private static int requestBufferSize= 4096;

 

           Public ChannelIO() throwsIOException{

                 this.socketChannel =socketChannel;

                 //设置模式为阻塞模式或非阻塞模式

                 socketChannel.configureBlocking(blocking);

                 requestBuffer =ByteBuffer.allocate(requestBufferSize);

}

 

Public SocketChannel getSocketChannel(){

      ReturnsocketChannel;

}

 

/**

*

*如果原缓冲区的剩余容量不够,就创建一个新的缓冲区,容量为原来的两倍,把原来缓冲区的数据复制到新缓冲区

*

/

Protected void resizeRequestBuffer(intremaining){

      If(requestBuffer.remaining()< remianing){

           //把容量增大到原来的两倍

           ByteBufferbb = ByteBuffer.allocate(requestBuffer.capcity()*2);

           //把极限设置为位置的值

           requestBuffer.flip();

           //把原来缓冲区中的数据复制到新的缓冲区

           bb.put(requestBuffer);

           requestBuffer= bb;

}

}

 

//接受数据,把它们存放到requestBuffer中,如果requestBuffer的剩余容量不足5%,就通过resizeRequestBuffer(int remaining)方法扩充容量

Public int read() throws IOException {

      resizeRequestBuffer(requestBufferSize/20);

      returnsocketChannel.read(requestBuffer);

}

 

 

//返回requestBuffer,它存放了请求数据

Public ByteBuffer getReadBuf(){

      ReturnrequestBuffer;

}

 

//发送参数指定的ByteBuffer中的数据

Public int write(ByteBuffer src) throwsIOException {

      ReturnsocketChannel.write(src);

}

 

//把FileChannel中的数据写到SocketChannel中

Public long transgerTo(FileChannel fc, longpos, long len) throws IOExcetion{

      Returnfc.transferTo(pos,len,socketChannel);

}

 

//关闭SocketChannel

Public void close() throws IOException{

      socketChannel.close();

}

}

 

 

java NIO概述相关推荐

  1. Java NIO系列教程(一) Java NIO 概述

    一.阻塞IO与非阻塞IO 阻塞IO: 通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至数据能够写入.传统的Server/Client模式会基于TP ...

  2. Java NIO(一) Java NIO 概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Sel ...

  3. java)_Java NIO系列教程(一) Java NIO 概述

    原文链接     作者:Jakob Jenkov     译者:airu     校对:丁一 Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Ja ...

  4. 转:Java NIO系列教程(一)Java NIO 概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Sel ...

  5. Java NIO概述(1)

    Java NIO是一个从Java 1.4开始就可以代替标准Java IO API的IO API,Java NIO提供了与标准IO不同的IO工作方式. Java NIO:通道和缓冲区(Channels ...

  6. JAVA NIO概述(一):I/O模型

    NIO是jdk1.4加入的新功能,我们一般成为非阻塞IO,在1.4之前,JAVA中的都是BIO(堵塞IO),BIO有以下几个缺点: 没有数据缓冲区,I/O性能存在问题 没有C/C++中channel( ...

  7. Java NIO系列教程(十二) Java NIO与IO

    原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov   译者:郭蕾    校对:方腾飞 当学习了Java ...

  8. Java NIO 系列教程 转

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...

  9. Java NIO 系列教程

    Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.本系列教程将有助于你学习和理解Java NIO. Java NIO提供了与 ...

最新文章

  1. java 锁_Java 锁之我见
  2. SparkSQL之关联mysql和hive查询
  3. 太棒了!港大同济伯克利推出目标检测新范式:Sparse R-CNN
  4. 服务器tomcat优化知识复习总结
  5. Error:Could not find com.android.tools.build:gradle:2.2.2.
  6. Sentinel 实战-控制台篇
  7. refprop物性库_refprop 9.1 下载-refprop(制冷剂物性查询运算软件)附中文教程 9.1 最新免费版 - 河东下载站...
  8. 2021年“泰迪杯”数据分析技能B题-肥料登记数据分析赛题
  9. Win 10 桌面简单美化(+开始菜单 TileGenie)
  10. 管家婆软件使用在线支付教程
  11. vue2实现电商后台管理的思路
  12. 计算机操作系统知识整理-计算机操作系统概述(计算机操作系统入门指南)
  13. 管理者如何制定团队目标?读完这篇你就懂了.
  14. 局域网服务器配置一个无线路由,局域网怎么增加无线路由器
  15. 【理解】Beta贝塔分布
  16. 智能、精准、节能丨极海APM32F103RCT7 LED车灯应用方案
  17. mysql备份导出数据库结构_MySql数据库导出完整版(导出数据库,导出表,导出数据库结构)详解...
  18. Typora如何将图片使用相对路径保存到统一文件夹中(解决.md文档传输丢图片的方法)
  19. SpelResolverConfigurationOnMissingBean.spelResolver 找不到方法问题
  20. 天梯选拔:先序序列创建二叉树,输出先序序列、中序序列、后序序列并输出叶子结点数

热门文章

  1. window系统查看端口被哪个进程占用了,并将它结束
  2. c语言switch循环语序,C语言初学者常见错误统计.doc
  3. node-OSDomainNetPath
  4. hdu4901 枚举状态(找集合对S(xor) ==T(and))
  5. hdu1816 + POJ 2723开锁(二分+2sat)
  6. 【Flutter】创建 Flutter 项目 ( Android Studio 创建并运行 Flutter 应用 | 命令行创建并运行 Flutter 应用 | 运行 Flutter 应用三种方式 )
  7. 一个操作读写已存在excel 文件的例子
  8. 实践作业3 (2017-12-4)
  9. [JLOI 2011]飞行路线[USACO 09FEB]Revamping Trails
  10. Linux 技巧:让进程在后台可靠运行的几种方法