Многопоточный Обозреватель - PullRequest
0 голосов
/ 10 мая 2019

Я пишу вид многопоточного обозревателя, и я сталкиваюсь с некоторыми проблемами проектирования.

Допустим, у меня есть какой-то пул потоков с очередью задач для набора данных. Некоторые из них предназначены только для чтения, другие переопределяют их.

После изменения данных я хочу выполнить notifyall (), чтобы наблюдатели могли обновить () свое состояние.

Потоки, которые выполняют задачу update (), я хочу, чтобы они были из другого пула второго потока.

И есть проблема: как заставить все потоки update () выполнить операцию обновления, прежде чем другая функция из первой очереди задач начнет изменять данные?

Я думаю о чем-то вроде передачи блокировки другому, конкретному потоку.

1 Ответ

0 голосов
/ 13 мая 2019

Если можете, избегайте использования замков.Это позволит избежать одновременной работы нескольких потоков.Если вам нужно вызвать update в другом потоке, потому что это требуется вашей инфраструктурой (например, потоком GUI), блокировки приведут к блокировке потока UI и снизят производительность.

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

Лучший способ - вообще не использовать общие объекты.Пусть один поток публикует неизменяемые события в очереди, которую другой поток может читать и обновлять на основе этих событий.

Если вам нужно использовать общие объекты, чтобы иметь возможность читать состояние объекта вна данный момент вы можете использовать Memento для создания снимка объекта, который можно прочитать из второго потока.

Если вам нужно получить все изменения из второго потока, вы можете сохранитьистория изменений в ваших объектах данных, так что поток udpate() может отслеживать, где он находится, и может читать новые изменения при получении уведомлений об изменениях.

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

Отметьте эту статью.Команда LMAX использует другой поток, имея только один поток для их BusinessLogic .Один поток получает события и помещает их в буфер.Другой поток, поток BusinessLogic с EventProcessor подбирает их и обрабатывает.Их решение работает в ситуациях, когда у вас есть один читатель с несколькими читателями, и каждый читатель может отслеживать, где он находится в буфере.В вашем случае, если у вас только два потока, вы можете сделать что-то вроде этого.

Вы также можете использовать Модель актера , где у вас есть несколько одновременно действующих лиц, которые работают вместе, отправляя сообщения между ними..

...