【问题标题】:Thread safe Ring Buffer线程安全的环形缓冲区
【发布时间】:2016-12-26 19:27:14
【问题描述】:

我有这个最大大小为 10 的环形缓冲区。有两个线程共享它的对象。一个线程推送新元素,另一个将其弹出。当缓冲区为空或已满时,线程应该等待而不是替换元素。 问题是跳过了一些随机字符。

public class CircularBuffer {
private byte[][] data = new byte[10][1024];
private int[] numRead = new int[10];
private int rp,wp,num;   //read pointer,write pointer,no of data
public boolean isReadComplete;
public boolean isComplete;
private final Lock lock = new ReentrantLock();
public CircularBuffer()
{
    rp=0;
    num=0;
    wp=0;
    isReadComplete=false;;
    isComplete=false;
}
public boolean isEmpty()
{
    if(num==0)
        return true;
    else
        return false;
}
public  void push(byte d[],int n)
{
    while(num==10){
        System.out.println("read waiting");
    }
    data[rp]=d;
    numRead[rp]=n;

    try{
        lock.lock();
        num++;
    }
    finally
    {
        lock.unlock();
    }
    if(rp==9)
        rp=0;
    else
        rp++;
}
public  boolean pop(Byt b)
{
    while(num==0){
        if(isReadComplete)
        {
            isComplete=true;
            System.out.println("Done writing");
            return true;

        }
        System.out.println("write waiting");

    }
    b.b=data[wp];
    b.numRead=numRead[wp];
    try{
        lock.lock();
        num--;
    }
    finally
    {
        lock.unlock();
    }
    if(wp==9)
        wp=0;
    else
        wp++;

     return false;
}

}

【问题讨论】:

  • 有一个无锁环形缓冲区here

标签: java multithreading data-structures buffer


【解决方案1】:

使用:

if(wp==9)
    wp=0;
else
    wp++;

在多线程环境中不好。一个线程很可能执行if(wp==9)并找到它false然后添加1,同时另一个线程刚刚找到8的值并将其增加到9。然后第一个线程是wp++,现在它拥有10

你应该使用类似的东西:

wp = (wp+1)%10;

你在其他地方也这样做。

这可能不是 问题,因为它会因IndexOutOfBoundsException 而崩溃,但它肯定是代码的一个问题。

【讨论】:

  • wp 仅由Read 线程使用。所以我认为这不会是一个问题。
猜你喜欢
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多