博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程安全的无锁RingBuffer
阅读量:6818 次
发布时间:2019-06-26

本文共 1440 字,大约阅读时间需要 4 分钟。

  RingBuffer是环形缓冲区,支持读和写两种操作,类似于循环队列。在实现上,一般用数组存储数据,同时设置双指针head和tail,head指向队首,tail指向队尾。读数据时,head++;写数据时,tail++。显然,RingBuffer不是线程安全的,需要对读写数据进行同步。然而,有一种特殊情况:一个线程读,一个线程写,在这种情况下可以实现线程安全的无锁RingBuffer,代码如下:

public class RingBuffer
{ private volatile T[] elements; private volatile int head; private volatile int tail; public RingBuffer(int capacity){ this.elements=(T[])new Object[capacity]; this.head=0; this.tail=-1; } private boolean isEmpty(){ return tail+1==head; } private boolean isFull(){ return tail+1-elements.length==head; } public void push(T element) throws IllegalArgumentException{ if(isFull()) throw new IllegalArgumentException("full queue"); elements[(tail+1)%elements.length]=element; tail++; } public T pop() throws IllegalArgumentException{ if(isEmpty()) throw new IllegalArgumentException("empty queue"); T element=elements[head%elements.length]; head++; return element; }}复制代码

  为什么上述代码能够确保线程安全?可以看到,创建RingBuffer后,只有写线程修改tail,只有读线程修改head,并且始终只有一个读线程,一个写线程,因此是没有并发写操作的。然而,由于读操作和写操作都不是原子性的,有可能读操作发生在写操作的过程中,写操作发生在读操作的过程中。这样会导致以下两个问题:

  • 对于读操作,当RingBuffer为空时,有可能读到还没写的数据。
  • 对于写操作,当RingBuffer为满时,有可能写到还没读的数据。

但是,对于写操作,我们是先修改elements,再修改tail;对于读操作,我们是先修改elements,再修改head。因此上述两个问题是不存在的,我们说上述RingBuffer是线程安全的,并且是无锁的,具有较高的性能。

转载于:https://juejin.im/post/5c32a1c26fb9a049b13e5bdf

你可能感兴趣的文章
mysql命令记录
查看>>
计算概论(A)/基础编程练习2(8题)/3:计算三角形面积
查看>>
AC日记——Andryusha and Socks Codeforces 780a
查看>>
markdown基本语法
查看>>
ArrayList和LinkedList区别
查看>>
深入tornado中的IOStream
查看>>
EasyUI DataGrid 分页示例
查看>>
ID基本操作(出血的定义)(置入图片)(添加页面)5.15
查看>>
0913数据库约束之主键 外键 非空 默认值约束 唯一约束 级联操作 表与表之间的联系...
查看>>
bzoj千题计划204:bzoj2813: 奇妙的Fibonacci
查看>>
卡尔曼滤波器原理之基本思想(一)
查看>>
微信 {"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"}
查看>>
appserv安装
查看>>
SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)
查看>>
2018-2019-2 20165325 《网络对抗技术》 Exp5:MSF基础应用
查看>>
Java基础扫盲系列(二)—— Java中BigDecimal和浮点类型
查看>>
如何在直播中解决黑屏、花屏、闪屏问题 | 直播疑难杂症排查
查看>>
js获取浏览器高度和宽度值(多浏览器)
查看>>
Deep learning:十六(deep networks)
查看>>
▲移动web前端开发
查看>>