Java: создать класс-посредник между несколькими потоками, обращающимися к несинхронизированному классу? - PullRequest
1 голос
/ 14 марта 2012

Итак, следуя подсказкам из этого вопроса Многопоточный доступ к файлу

Мой сценарий состоит в том, что у меня есть компонент электронной таблицы, в котором несколько потоков будут получать доступ и записывать в каждую книгу.Сам компонент не является потокобезопасным, и поэтому я прав, считая, что пока поток записывает в него, другой поток должен быть заблокирован, пока первый не закончит запись?Как я собираюсь достичь этого, когда имею дело с не-потокобезопасным классом?Поместить метод записи в синхронизированный блок?

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

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

По сути, каждый поток делает две вещи сам по себе.1) выполняет длительную обработку данных из каждого соответствующего источника, 2) записывает обработанные данные в электронную таблицу.Я ищу параллельное решение, когда 1) не сталкивается с «ожиданием» из-за 2).

1 Ответ

1 голос
/ 14 марта 2012

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

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

Здесь может быть место для распараллеливания работников очереди, поскольку они могут связываться друг с другом и делать между собой некоторую блокировку на основе строк. Например, если первой операцией является чтение строк 1-4 и запись в строку 5, а второй операцией является чтение строк 6-10 и запись в строку 11, то они должны выполняться параллельно. Но будьте осторожны, так как это может зависеть от базовой структуры таблицы, которая, как вы говорите, не является поточно-ориентированной. Тем не менее, чтение, вероятно, хорошо для параллельного выполнения.

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

Тем не менее, лучшим решением будет использование многопоточной электронной таблицы или использование только одного потока для доступа к ней. Почему бы не использовать электронную таблицу на основе базы данных, а затем иметь несколько потоков для чтения / записи базы данных одновременно?

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