[Getting to give up -Java] concurrent programming -NIO-Buffer

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.

Guess you like

Origin blog.csdn.net/yunqiinsight/article/details/95045970