Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
Всем привет!

Получаю объекты из очереди ActiveMQ через MessageListener onMessage.
Сообщения накапливаются в ArrayList objectList.
При первом запуске onMessage запускается ScheduledExecutorService executorFlushSchedule. И по прошествии flushDBTimer секунд и если в objectList есть объекты, происходит сброс накопленных объектов в БД через метод flushToDB() и далее очистка objectList.
Получается общий ресурс objectList и 2 потока: метод onMessage и executorFlushSchedule.

Как в данном случае правильно поставить блокировку на objectList?

@Override
    public void onMessage(Message message) {
        if (executorFlushSchedule == null) {
            executorFlushSchedule 
                    = Executors.newSingleThreadScheduledExecutor();
            executorFlushSchedule.scheduleAtFixedRate(
                    () -> {
                        if (objectList.size() > 0) {
                            flushToDB();
                        }
                    },
                    0,
                    flushDBTimer,
                    TimeUnit.SECONDS);
        }
        
        try {
            objectList.add((T) ((ObjectMessage) message).getObject());
        } catch (JMSException ex) {
            throw new RuntimeException(exceptionOnMessage, ex);
        }
    }
19 июн 19, 18:07    [21911787]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Lelouch
Member

Откуда: Москва
Сообщений: 1782
Molasar,

1) ReentrantLock тут не нужен
2) Необходима синхронизация при создании ScheduledExecutor (да и вообще - погуглите про double-checked locking)
3) Проще всего - обернуть List с помощью Collections.synchronizedList(), но я бы посмотрел в сторону реализаций BlockingQueue (add/offer для добавления, drainTo для получения записей для вставки)
19 июн 19, 18:17    [21911789]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
забыл ник
Member

Откуда:
Сообщений: 3024
почему ReentrantLock?

Вообще самый простой способ - это обернуть все обращения к objectList в synchronised блок
19 июн 19, 18:21    [21911791]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Lelouch
Member

Откуда: Москва
Сообщений: 1782
Lelouch
3) Проще всего - обернуть List с помощью Collections.synchronizedList()

P.S. Правда в этом случае есть подводные камни (например, нельзя использовать итератор), поэтому лучше или BlockingQueue или блоки синхронизации, как написали выше.
19 июн 19, 18:59    [21911813]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
andreykaT
Member

Откуда:
Сообщений: 2420
блокингкью для таких целей юзают.
19 июн 19, 19:26    [21911824]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
Спасибо, бум думать
20 июн 19, 10:01    [21912028]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Зачем ему еще одна queue?
20 июн 19, 10:41    [21912052]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
mayton
Зачем ему еще одна queue?


это типа буфера, видимо, для bulk insert в базу.
20 июн 19, 14:58    [21912278]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Озверин
mayton
Зачем ему еще одна queue?


это типа буфера, видимо, для bulk insert в базу.
имхо лишнее.
BlockingQueue читает вставляющий поток и вставляет.
20 июн 19, 16:04    [21912329]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Архитектурно не вижу смысла. У кого есть строгое объяснение зачем нужна 2-я очередь - отпишитесь.
20 июн 19, 16:18    [21912345]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7902
И по прошествии flushDBTimer секунд и если в objectList есть объекты, происходит сброс накопленных объектов в БД через метод flushToDB() и далее очистка objectList.

Не очень понятно, зачем вообще блокировка:

1. Заполняем ArrayList в потоке читателе-ActiveMQ
2. По накоплению нужного размера, передаем ЦЕЛИКОМ ArrayList в поток писатель-в-базу
3. Создаем новый ArrayList

Но. возможно, я просто чего-то не понимаю

IMHO
20 июн 19, 16:25    [21912356]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
Leonid Kudryavtsev
И по прошествии flushDBTimer секунд и если в objectList есть объекты, происходит сброс накопленных объектов в БД через метод flushToDB() и далее очистка objectList.

Не очень понятно, зачем вообще блокировка:

1. Заполняем ArrayList в потоке читателе-ActiveMQ
2. По накоплению нужного размера, передаем ЦЕЛИКОМ ArrayList в поток писатель-в-базу
3. Создаем новый ArrayList

Но. возможно, я просто чего-то не понимаю

IMHO


мое мнение такое, что :
- тс использует достаточно надежный источник сообщений - activemq и беспокоится об их(сообщениях) сохранности
- тс использует надежное хранилище для сообщений
- тс вдруг хранит сообщения в arraylist, где может их потерять

Я скорее в этом логики не вижу. То есть, допустим, встваить данные не удалось? Что дальше то с ними делать? Надо обработку для этого придумать как минимум. Или outofmemory случился....
И все - 10000 событий исчезли и никто о них не узнает...
20 июн 19, 16:33    [21912360]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Вот этот пункт непонятен.
Сообщения накапливаются в ArrayList objectList.

Накапливаются для чего?
20 июн 19, 16:39    [21912364]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Leonid Kudryavtsev,
Если о BlockingQueue то там блокировка нужна чтобы при MAX 1000. Пищущий поток встал и не мог записать 1001-й.
Так как очередь вероятно никто не выгребает.
..
Тут как обычно всез собак вешают на слабое место.
20 июн 19, 16:39    [21912365]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7902
PetroNotC Sharp
Если о BlockingQueue то там блокировка нужна чтобы при MAX 1000. Пищущий поток встал и не мог записать 1001-й. Так как очередь вероятно никто не выгребает.


AFAIK
Нормальные люди (не создатели Java), для этого используют Circle Ring Buffer. Но создатели Java, не позаботились реализовать его в java.util (((
20 июн 19, 16:54    [21912374]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Leonid Kudryavtsev
PetroNotC Sharp
Если о BlockingQueue то там блокировка нужна чтобы при MAX 1000. Пищущий поток встал и не мог записать 1001-й. Так как очередь вероятно никто не выгребает.


AFAIK
Нормальные люди (не создатели Java), для этого используют Circle Ring Buffer. Но создатели Java, не позаботились реализовать его в java.util (((

Подобное реализовано в библиотеке Disruptor. И уже например используется в асинхронных логгерах Log4j2
при правильной настройке. Но я сомневаюсь что автору это нужно. Дизраптор создавался для высокочастотного
трейдинга.
20 июн 19, 17:32    [21912401]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3334
Озверин
мое мнение такое, что :
- тс использует достаточно надежный источник сообщений - activemq и беспокоится об их(сообщениях) сохранности
- тс использует надежное хранилище для сообщений
- тс вдруг хранит сообщения в arraylist, где может их потерять

Я скорее в этом логики не вижу. То есть, допустим, встваить данные не удалось? Что дальше то с ними делать? Надо обработку для этого придумать как минимум. Или outofmemory случился....
И все - 10000 событий исчезли и никто о них не узнает...

вроде все понятно: у ТС spring-jms, который вычитывает сообщения по одному и отдает их в обработку, в связи с чем у ТС проблемы с производительностью (наверное просадка порядками исчисляется), поэтому он принял решение, что в базу их нужно вливать батчами, здесь очевидно, что задача не так решается: нужно батчами читать и батчами писать, а не изворачиваться хранением в памяти и потоками.
20 июн 19, 18:17    [21912432]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Molasar вообще не говорит ничего про производительность. Остается только гадать где там узкое место.
Возможно - это предположение на основе его прошлых постов?

В любом случе нужны хоть какие-то цифры. И хотя-бы 2 эксперимента.
Чтение просто сообщений из ActiveMQ без записи в БД. И наоборот.
20 июн 19, 18:56    [21912456]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3334
mayton
Molasar вообще не говорит ничего про производительность. Остается только гадать где там узкое место.
Возможно - это предположение на основе его прошлых постов?

Как ускорить запись в таблицу через JDBC?
20 июн 19, 19:07    [21912460]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42343
Да я помню это.
20 июн 19, 19:08    [21912462]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3334
Molasar,

в классе:
private final AtomicReference<List<?>> queue = new AtomicReference<>(new ArrayList<>());

при добавлении:
queue.get().add(object)

при записи в БД:
List<?> objects = queue.getAndSet(new ArrayList<>())
20 июн 19, 19:17    [21912463]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3334
ой нет, фигню написал
20 июн 19, 19:28    [21912467]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
Андрей Панфилов
mayton
Molasar вообще не говорит ничего про производительность. Остается только гадать где там узкое место.
Возможно - это предположение на основе его прошлых постов?

Как ускорить запись в таблицу через JDBC?

Я помню. Выложу цифры чуть позже.
24 июн 19, 14:51    [21914130]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
Озверин
Leonid Kudryavtsev
пропущено...

Не очень понятно, зачем вообще блокировка:

1. Заполняем ArrayList в потоке читателе-ActiveMQ
2. По накоплению нужного размера, передаем ЦЕЛИКОМ ArrayList в поток писатель-в-базу
3. Создаем новый ArrayList

Но. возможно, я просто чего-то не понимаю

IMHO


мое мнение такое, что :
- тс использует достаточно надежный источник сообщений - activemq и беспокоится об их(сообщениях) сохранности
- тс использует надежное хранилище для сообщений
- тс вдруг хранит сообщения в arraylist, где может их потерять

Я скорее в этом логики не вижу. То есть, допустим, встваить данные не удалось? Что дальше то с ними делать? Надо обработку для этого придумать как минимум. Или outofmemory случился....
И все - 10000 событий исчезли и никто о них не узнает...

Логика следующая:
1. Приложения кидают сообщения в очередь ActiveMQ
2. Слушатель ActiveMQ считывает сообщения по одному из очереди.
3. Если писать в базу по одному сообщению, то получается очень медленно. Поэтому приходится накапливать сообщения в списке и сбрасывать их по таймеру в БД как пакет Производительность увеличивается на порядок.
4. До комита в БД ловим эксепшены и возвращаем все сообщения в очередь.
А как по другому?
24 июн 19, 14:59    [21914138]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Molasar
Если писать в базу по одному сообщению, то получается очень медленно. Поэтому приходится накапливать сообщения в списке и сбрасывать их по таймеру в БД как пакет Производительность увеличивается на порядок.
для пакетной записи не нужен таймер
24 июн 19, 15:24    [21914163]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Molasar,
Покажи код п.п.2
24 июн 19, 15:26    [21914165]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
PetroNotC Sharp
Molasar
Если писать в базу по одному сообщению, то получается очень медленно. Поэтому приходится накапливать сообщения в списке и сбрасывать их по таймеру в БД как пакет Производительность увеличивается на порядок.
для пакетной записи не нужен таймер

Почему?
24 июн 19, 17:18    [21914273]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Molasar,
Посмотри любой jdbc код цикла с отправкой. Где там таймер?
Давай ближе к коду. Где он?
Читать из очереди можно самому и выбрать по 500 сообщений и можно листенером 500 раз накапливая.
Зачем таймер?
24 июн 19, 17:30    [21914290]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
Molasar
Member

Откуда:
Сообщений: 756
PetroNotC Sharp
Molasar,
Посмотри любой jdbc код цикла с отправкой. Где там таймер?
Давай ближе к коду. Где он?
Читать из очереди можно самому и выбрать по 500 сообщений и можно листенером 500 раз накапливая.
Зачем таймер?

Код и цифры чуть позже.
Вы накопили 499 сообщений, а 500-е приходит через 30 мин. Будете ждать? Вот для этого и нужен таймер.
Сброс сообщения в базу происходит по таймеру, либо счётчику, что быстрее наступит.
25 июн 19, 09:15    [21914551]     Ответить | Цитировать Сообщить модератору
 Re: Как работает ReentrantLock?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2041
Molasar
Код и цифры чуть позже.
вот все и ждем. Так как решения от цифр могут развернуться на 180град.

Molasar
Вы накопили 499 сообщений, а 500-е приходит через 30 мин. Будете ждать?

Вы определитесь.
То выговорите, что в секунду тысячи сообщений. То городите таймер что 30 мин не булет ни одного.
Поймите, для одного ТЗ это будет супер решение. Для другог говнокод.
25 июн 19, 10:28    [21914611]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Java Ответить