Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程安全循环缓冲区?_Java_Thread Safety - Fatal编程技术网

Java 线程安全循环缓冲区?

Java 线程安全循环缓冲区?,java,thread-safety,Java,Thread Safety,我有两个线程,一个线程插入数据,第二个线程检索数据。 我得到了非常奇怪的结果 它是线程安全的吗 如果没有,如何修复 这是我的循环缓冲区: private int mBufferSize; private int startPointer = 0; private int endPointer = 0; private int bufferSize = 0; private String[] buffer; public BBuffer(int size)

我有两个线程,一个线程插入数据,第二个线程检索数据。
我得到了非常奇怪的结果

它是线程安全的吗

如果没有,如何修复

这是我的循环缓冲区:

private int mBufferSize;
    private int startPointer = 0;
    private int endPointer = 0;
    private int bufferSize = 0;
    private String[] buffer;

    public BBuffer(int size) {
        mBufferSize = size;
        startPointer = 0;
        endPointer = 0;
        bufferSize = 0;
        buffer = new String[mBufferSize];
    }


    public String[] getData() {
        String data = null;

        if (!isEmpty()) {
            bufferSize--;
            startPointer = (startPointer + 1) % mBufferSize;
            data = (String) buffer[startPointer];


        } else {

            System.err.println("!");
            return null;
        }

        return data.split(",");
    }

    public  void addData(String data) {
        if (!isFull()) {
            bufferSize++;
            endPointer = (endPointer + 1) % mBufferSize;
            buffer[endPointer] = data;
            System.out.println("->"+data);
        } else {
            System.out.println("full");
        }
    }

    public boolean isEmpty() {
        return bufferSize == 0;
    }

    public boolean isFull() {
        return bufferSize == mBufferSize;
    }

}
不,它不是线程安全的。 如果从两个不同的线程调用
getData()
addData()
,那么您100%肯定会遇到问题,主要是因为
bufferSize
将由两个线程访问;一个调用
getData()
,另一个调用
addData()
。 要解决此问题,应首先获取锁,然后再修改
bufferSize
成员变量。 应该可以帮助您开始使用线程和锁,以及如何保护共享资源。

不,它不是线程安全的。 如果从两个不同的线程调用
getData()
addData()
,那么您100%肯定会遇到问题,主要是因为
bufferSize
将由两个线程访问;一个调用
getData()
,另一个调用
addData()
。 要解决此问题,应首先获取锁,然后再修改
bufferSize
成员变量。
应该可以帮助您开始使用线程和锁以及如何保护共享资源。

为此,您使用了一个信号量,因为您使用的是基本数组。ArrayList可以用作线程安全的方法。但是在您的实现中,您希望创建一个信号量,然后在每个使用缓冲区的方法中调用semaphore.aquire(),完成后调用semaphore.release()

,因为您使用的是基本数组,所以要使用一个信号量。ArrayList可以用作线程安全的方法。但是在您的实现中,您希望创建一个信号量,然后在每个使用缓冲区的方法中调用semaphore.aquire(),完成后调用semaphore.release()

根本不是线程安全的

您只需在4个方法的声明中添加
synchronized
关键字。幸运的是,这样一个简单的解决方案适用于您的类,因为情况并非总是如此


一个潜在的棘手问题是
getData
返回的
String[]
。每次调用时都会创建一个新数组,这样就不会有任何问题,但如果它返回了对内部数组的引用,则同步会很复杂。

根本不是线程安全的

您只需在4个方法的声明中添加
synchronized
关键字。幸运的是,这样一个简单的解决方案适用于您的类,因为情况并非总是如此


一个潜在的棘手问题是
getData
返回的
String[]
。每次调用时都会创建一个新数组,这样就不会有任何问题,但如果它返回了对内部数组的引用,则同步会很复杂。

这是家庭作业吗?如果是这样的话,你能给它贴上“家庭作业”的标签吗?我怀疑addData和getData应该是同步的。如果一个线程调用加法,而另一个线程在get中,或者VICA反之亦然,比如说,在DIV操作符的毛茸茸的数学的中间,坏事可能发生。这是一个作业吗?如果是这样的话,你能给它贴上“家庭作业”的标签吗?我怀疑addData和getData应该是同步的。如果一个线程调用加法,而另一个线程在get中,或者VICA反之亦然,比如说,在DIV操作符的毛茸茸的数学的中间,坏的事情可能发生。请解释一下为什么同步关键字在这种情况下足够了?thanksEach方法使对象保持一致状态。反例是一个具有方法
setFirstName
setLastName
的类;即使这两种方法都是同步的,在某些时间段内,对象的状态也不一致,其名字与姓氏不一致。请您进一步解释一下,为什么在这种情况下同步关键字就足够了?thanksEach方法使对象保持一致状态。反例是一个具有方法
setFirstName
setLastName
的类;即使这两个方法都是同步的,您也会有一些时间段,其中对象的状态不一致,其名字与姓氏不一致。