Поток безопасный круговой буфер? - PullRequest
0 голосов
/ 08 декабря 2011

Я получил 2 потока, один вставляет данные, а второй поток получает данные.
Я получил очень странные результаты.

Поток безопасен?

если нет, то как это исправить?

это мой круговой буфер:

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;
    }

}

Ответы [ 3 ]

3 голосов
/ 08 декабря 2011

Совсем не безопасен для потоков.

Вам просто нужно добавить ключевое слово synchronized к объявлению ваших 4 методов.Вам повезло, что такое простое решение работает для вашего класса, потому что это не всегда так.

Одна потенциально сложная проблема - это String[], возвращаемый getData.Вы создаете новый массив при каждом вызове, поэтому у вас не возникает никаких проблем, но было бы сложно синхронизировать, если бы он возвращал какую-то ссылку на внутренний массив.

0 голосов
/ 08 декабря 2011

Для этого вы используете семафор, так как вы используете базовый массив.Arraylists можно использовать в качестве многопоточного метода.Но с вашей реализацией вы хотите создать семафор, затем в каждом методе, который использует буферный вызов semaphore.aquire (), а когда вы закончите, вызовите semaphore.release ()

0 голосов
/ 08 декабря 2011

Нет, это не потокобезопасно. Если getData() и addData() вызываются из 2 разных потоков, то вы на 100% уверены, что у вас возникнут проблемы в основном потому, что к bufferSize будут обращаться оба потока; один зовет getData(), а другой зовет addData(). Чтобы это исправить, вы должны сначала получить блокировку перед изменением переменной-члена bufferSize. Это должно помочь вам начать работу с потоками и блокировками и узнать, как защитить общие ресурсы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...