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.
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.
, assumingBufferthe length isbuffersize.we set two pointers. HEADpoint to the next read position, andTailpoints to the next write location. Since this is a ringbuffer (ring buffer), here's a question, how to judgeBufferis full or empty. The rules used here are thatBufferthe last cell does not store data. So, ifhead = = Tail, then explainBufferis empty. Ifhead = = tail + 1 (mod buffersize), then explainBufferit's full.
And then there's the most important thing: how to Thread-safe in a lock-free wayBufferread and write operations. The rationale is this. When we do the reading, we only modify theHeadwhile writing, we only modify the value of theTailthe value. While writing, we are writing content to theBufferbefore modifyingTailWhile the read operation is performed, we read the value of theTailvalue and assigns it to theCopytail. An assignment operation is an atomic operation. So when I read thatCopytailafter that, fromHeadto theCopytailthere must be data that can be read, and no data will be read without writing. Similarly, the read operation is completed before it is modifiedHeadand is read before the write operation.Headvalue to determine if there is room to write the data. So, at this timeTailto thehead-1there must be room for the data to be written, without the presence of a location where the data has not been read out and overwritten by the write operation. This will guarantee theRingbufferof thread security.
Finally, attach the code for reference. Welcome to criticize correct, also welcome various discussions!
1 Public classRingbuffer {2 3 Private Final Static intbuffersize = 1024;4 Privatestring[] Buffer =NewString[buffersize];5 Private intHead = 0;6 Private intTail = 0;7 8 PrivateBoolean Empty () {9 returnHead = =tail;Ten } One PrivateBoolean Full () { A return(tail + 1)% buffersize = =head; - } - PublicBoolean put (String v) { the if(Full ()) { - return false; - } -Buffer[tail] =v; +Tail = (tail + 1)%buffersize; - return true; + } A PublicString Get () { at if(Empty ()) { - return NULL; - } -String result =Buffer[head]; -Head = (head + 1)%buffersize; - returnresult; in } - Publicstring[] GetAll () { to if(Empty ()) { + return NewString[0]; - } the intCopytail =tail; * intCNT = Head < tail? Tail-head:buffersize-head +tail; $String[] result =Newstring[cnt];Panax Notoginseng if(Head <copytail) { - for(inti = head; i < tail; i++) { theResult[i-head] =Buffer[i]; + } A}Else { the for(inti = head; i < buffersize; i++) { +Result[i-head] =Buffer[i]; - } $ for(inti = 0; i < tail; i++) { $Result[buffersize-head + i] =Buffer[i]; - } - } theHead =tail; - returnresult;Wuyi } the}
Implementation of thread-safe lock-free Ringbuffer