首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

NIO Channel和Buffer(2)

NIO Channel和Buffer(2)

ByteBuffer
A byte buffer,extend from Buffer
ByteBuffer的实现类包括HeapByteBuffer和DirectByteBuffer两种。
  • HeapByteBuffer
    public static ByteBuffer allocate(int capacity) {  if (capacity < 0)      throw new IllegalArgumentException();  return new HeapByteBuffer(capacity, capacity);}HeapByteBuffer(int cap, int lim) {    super(-1, 0, lim, cap, new byte[cap], 0);}HeapByteBuffer通过初始化字节数组hd,在虚拟机堆上申请内存空间。
  • DirectByteBuffer
    public static ByteBuffer allocateDirect(int capacity) {  return new DirectByteBuffer(capacity);}DirectByteBuffer(int cap) {  super(-1, 0, cap, cap);  boolean pa = VM.isDirectMemoryPageAligned();  int ps = Bits.pageSize();  long size = Math.max(1L, (long)cap + (pa ? ps : 0));  Bits.reserveMemory(size, cap);  long base = 0;  try {      base = unsafe.allocateMemory(size);  } catch (OutOfMemoryError x) {      Bits.unreserveMemory(size, cap);      throw x;  }  unsafe.setMemory(base, size, (byte) 0);  if (pa && (base % ps != 0)) {      // Round up to page boundary      address = base + ps - (base & (ps - 1));  } else {      address = base;  }  cleaner = Cleaner.create(this, new Deallocator(base, size, cap));  att = null;}DirectByteBuffer通过unsafe.allocateMemory在物理内存中申请地址空间(非jvm堆内存),并在ByteBuffer的address变量中维护指向该内存的地址。
    unsafe.setMemory(base, size, (byte) 0)方法把新申请的内存数据清零。
Channel
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
又称“通道”,NIO把它支持的I/O对象抽象为Channel,类似于原I/O中的流(Stream),但有所区别:
  • 流是单向的,通道是双向的,可读可写。
  • 流读写是阻塞的,通道可以异步读写。
  • 流中的数据可以选择性的先读到缓存中,通道的数据总是要先读到一个缓存中,或从缓存中写入,如下所示:

Channel.png

目前已知Channel的实现类有:
  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel
返回列表