In programming, we sometimes encounter situations where one thread writes data into a buffer and another thread reads data from it. So there is the problem of multi-threading competition. The usual solution is to lock up competing resources. However, the general lock loss is higher. In fact, for such a thread to write, a thread read the special case, can be a simple lock-free ringbuffer to achieve. This makes the code very efficient to run.
This article draws on the Disruptor project code.
Code I put a copy on GitHub, the students I need to download (Ringbuffer.java). A copy will be attached at the end of this article.
The basic principles of the Code are as follows.
, assuming that the length of buffer is buffersize. We set two pointers. The head points to the next read position, and tail points to the next write position. Since this is the ring buffer, there is a problem here, how to tell if buffer is full or empty. The rule here is that the last cell in buffer does not store data. So, if head = = tail, then the buffer is empty. If head = = tail + 1 (mod buffersize), then the buffer is full.
The next step is the most important: how to read and write a thread-safe buffer in a lock-free manner. The rationale is this. When we do the reading, we only change the value of the head, and in the writing we only modify the value of the tail. In the write operation, we modify the value of the tail after writing the content to buffer, while in the read operation we read the value of the tail and assign the value to Copytail. An assignment operation is an atomic operation. So after reading the Copytail, from head to Copytail there must be data to read, there is no data not written to read operation. Similarly, the value of the head is not modified until the read operation is completed, and the values of the head are read before the write operation to determine if there is room to write the data. So, at this time tail to head-1 there must be room to write data, and do not appear a position of the data has not been read out on the case of written operation coverage. This guarantees the thread safety of the Ringbuffer.
Finally, attach the code for reference. Welcome to criticize correct, also welcome various discussions!
1 public class Ringbuffer {2 3 private final static int buffersize = 1024x768; 4 private string[] buffer = new Stri Ng[buffersize]; 5 private int head = 0; 6 private int tail = 0; 7 8 Private Boolean empty () {9 return head = = tail;10}11 private Boolean full () {+ RET Urn (tail + 1)% buffersize = = head;13}14 public Boolean put (String v) {if (full ()) {+ RE Turn false;17}18 buffer[tail] = v;19 tail = (tail + 1)% buffersize;20 return true;21 }22 public string Get () {(empty ()) {null;25}26 string result = B UFFER[HEAD];27 head = (head + 1)% buffersize;28 return result;29}30 public string[] GetAll () {31 if (empty ()) {return new string[0];33}34 int copytail = tail;35 int cnt = Head < Copytail? Copytail-head:buffersize-head + copytail;36 String[] result = new string[cnt];37 if (Head < Copytail) {$ for (int i = head; I < COPYT Ail i++) {Result[i-head] = buffer[i];40}41} else {for (int i = head; i < buffersize; i++) {Result[i-head] = buffer[i];44}45 for (int i = 0; i < copytail; i++) {Result[buffersize-head + i] = buffer[i];47}48}49 head = copytail;50 Return result;51}52}
Implementation of thread-safe lock-free Ringbuffer