Foreword
Part I [from] the entry to abandon -Java concurrent programming -NIO-Channel , we learned channel is a two-way channel, data channel can be transmitted in both directions entity (file, socket) and buffer (buffer) in.
In this article we will learn next buffer
Brief introduction
That buffer buffer, in fact, is a memory, it can be used to write, read data. It is a linear, finite size, the order of data bearer type memory block basis.
buffer has three important properties:
- capacity: buffer pool size, are immutable. When the buffer is full, you need to clear in order to continue writing.
- limit: is the position of the first element of the buffer can not be read or written, the size limit never exceed the capacity (in write mode, limit equal capacity)
- position: position of the first element is the buffer can be read or written, position size never exceeds the limit
In addition boolean, each corresponding to a basic data type has a buffer. This Such as: ByteBuffer, CharBuffer, LongBuffer etc.
buffer is not thread safe, if you want to use in multiple threads need to lock control
Next to start learning ByteBuffer, for example.
ByteBuffer
allocateDirect
public static ByteBuffer allocateDirect(int capacity) {
//会创建一个容量大小为capacity的DirectByteBuffer(ByteBuffer的子类)
return new DirectByteBuffer(capacity);
}
allocate
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw createCapacityException(capacity);
//会创建一个容量大小为capacity的HeapByteBuffer(ByteBuffer的子类)
return new HeapByteBuffer(capacity, capacity);
}
HeapByteBuffer and DirectByteBuffer difference:
- DirectByteBuffer is directly call native methods :: malloc in the native os () to create a heap outside the memory; HeapByteBuffer is directly allocated on the heap memory in the jvm.
- When the interaction buffer data and disks, networks, etc. have occurred in the operating system kernel, using DirectByteBuffer can be prevented from kernel mode -, all processing performed> switching overhead kernel mode in the kernel, -> user mode performance will be better
- When the frequent creation data than a smaller buffer when using HeapByteBuffer in jvm heap memory allocation can offset the benefits DirectByteBuffer brought out to use.
wrap
public static ByteBuffer wrap(byte[] array,
int offset, int length)
{
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
public static ByteBuffer wrap(byte[] array) {
return wrap(array, 0, array.length);
}
The packed into a byte array ByteBuffer
Read Data
- Using the get method of reading data from the Buffer
- To read data from the Buffer i.e. Channel: Channel :: write () (read data from the write buffer to the resource, it is a write)
Write data
- The method of use put the data directly in Buffer
- To read data from the Channel Buffer namely: Channel :: read () (read data is written into the buffer from the resources, it is read)
position
//获取buffer中当前position的位置
public final int position() {
return position;
}
//设置buffer的position为newPosition,注意newPosition要大于0且小于limit,如果remark大于newPosition则设置为-1
public Buffer position(int newPosition) {
if (newPosition > limit | newPosition < 0)
throw createPositionException(newPosition);
position = newPosition;
if (mark > position) mark = -1;
return this;
}
limit
//获取buffer中当前limit的位置
public final int limit() {
return limit;
}
//设置buffer的limit为newLimit,注意newLimit要大于0且小于capacity。如果position大于newLimit这设置为newLimit,如果remark大于newLimit则设置为-1
public Buffer limit(int newLimit) {
if (newLimit > capacity | newLimit < 0)
throw createLimitException(newLimit);
limit = newLimit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
mark
public Buffer mark() {
//标记mark为当前position
mark = position;
return this;
}
The current position of the mark, when using the reset method, you can return to the current position of the mark
reset
public Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
//设置position为当前mark
position = m;
return this;
}
Back to previous mark set position
clear
public Buffer clear() {
//设置position为0
position = 0;
//limit设置为capacity大小
limit = capacity;
//mark设置为-1(初始化)
mark = -1;
return this;
}
After reading the data call clear, about to empty the buffer logic, data can be written from 0
flip
public Buffer flip() {
//limit设置为当前位置
limit = position;
//position设置为0
position = 0;
//mark设置为-1(初始化)
mark = -1;
return this;
}
The buffer is provided from write mode to read mode, set to the current position of the position limit, i.e., only read data size limit
rewind
public Buffer rewind() {
position = 0;
mark = -1;
return this;
}
The position is set to 0, i.e., reading from the beginning
remaining
public final int remaining() {
return limit - position;
}
In return how much byte buffer is unread
hasRemaining
public final boolean hasRemaining() {
return position < limit;
}
It has been read
compact
public ByteBuffer compact() {
System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
position(remaining());
limit(capacity());
discardMark();
return this;
}
The position limit and direct data to the start of byteBuffer copy of the read data empty, and set the new end of the current position of unread data. This avoids the problem clear method will not read data also cleared
slice
public ByteBuffer slice() {
return new HeapByteBufferR(hb,
-1,
0,
this.remaining(),
this.remaining(),
this.position() + offset);
}
ByteBuffer slice(int pos, int lim) {
assert (pos >= 0);
assert (pos <= lim);
int rem = lim - pos;
return new HeapByteBufferR(hb,
-1,
0,
rem,
rem,
pos + offset);
}
Create a new ByteBuffer, the cache distinguish piece, set up a sub-buffer memory or in fact shared data changes, two buffers the data will be read after the change.
to sum up
Buffer three most important attributes: position, limit, capacity. When these three properties to keep in mind the meaning and read switch settings change how the core knowledge of Buffer mastered.
Original link
This article Yunqi community original content may not be reproduced without permission.