Как прочитать последние X записей вектора, будучи потокобезопасным? - PullRequest
0 голосов
/ 17 февраля 2012

У меня есть одноэлементный регистратор, который содержит вектор.Объекты извне могут добавлять информацию к этому вектору, вызывая singletonLogger.append (String data) и считывать весь вектор, вызывая singletonLogger.getLogEntries (), которая возвращает строку.Было бы неплохо перегрузить метод getLogEntries с помощью параметра int, например, getLogEntries (int x), чтобы иметь возможность получать только последние x записей вместо всего журнала.это было бы легко, что-то вроде:

String getLogEntries(int x) {

int size = vector.size();

for(int i = size; i > (size - x); i--) {

    // StringBuilder.append(vector.elementAt....

 }
}

Но, конечно, это не совсем безопасно, если учитывать несколько потоков.Представьте, что вектор очищается другим методом вскоре после того, как его размер был определен описанным выше методом, цикл завершится сбоем.

С другой стороны, я не хочу помечать весь метод как синхронизированный, посколькуобработка может длиться 5 - 10 секунд.Это блокирует весь код, который пытается вызвать методы регистратора, верно?

Есть ли другой способ надежно получить последние x элементов вектора?

Спасибо

Ответы [ 2 ]

2 голосов
/ 17 февраля 2012

Редактировать

Vector имеет метод sublist , который должен работать и синхронизироваться, но это не решает проблему очистки Vector в другом потоке. Вы можете использовать ReadWriteLock и получить readLock() при чтении с конца Vector с использованием sublist() и writeLock() (что гарантирует эксклюзивный доступ), когда необходимо clear() называется. Если ваш фоновый поток записывает записи журнала на диск или что-то в этом роде, он должен посчитать количество записанных строк, а затем получить writeLock() и удалить их в начале списка вместо вызова clear(). Это ограничило бы время под замком, чтобы быть более эффективным.

Вы можете также рассмотреть возможность ведения собственной внутренней очереди, чтобы вы могли конкретно управлять синхронизацией. Это может облегчить очистку более ранних записей из очереди. Опять же, вам может понадобиться ReadWriteLock для этого.

1 голос
/ 17 февраля 2012

Рассматривали ли вы копирование соответствующих элементов в новый Vector в блоке synchronized и последующую обработку их вне одного?

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