Что делать, если одна библиотека не многопоточная? - PullRequest
4 голосов
/ 23 марта 2010

Я бы хотел многопоточное приложение, однако одна библиотека, которую я использую, не поддерживает многопоточность (я не знаю, какое слово «синхронизировано»).

Какие у меня варианты?

Насколько я знаю, между потоками и процессами (Runtime.exec) в Java нет ничего (нет абстракции в jvm, чтобы иметь что-то вроде изолированного "процесса Java").

Как бы вы справились с этим?

EDIT

Спасибо за ответ, еще раз, один уровень косвенности делает свое дело.

Ответы [ 5 ]

11 голосов
/ 23 марта 2010

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

Или вы можете создать потокобезопасную оболочку вокруг нее.

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

Обновление: , как указал @Wim, если библиотека управляет глобальным состоянием, вы должны иметь поточно-ориентированную оболочку, чтобы гарантировать, что изменения становятся видимыми между потоками.

6 голосов
/ 23 марта 2010

Я бы создал Фасад, а не использовал бы библиотеку напрямую. Затем Фасад должен синхронизировать соединение / звонки в библиотеку.

Что-то вроде:

External Call    External Call    External Call
      |               |                |
      ----------------------------------             
                    Wrapper
                      |
                   Library

Обновление:

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

3 голосов
/ 23 марта 2010

Количество зависит от размера библиотеки и того, для чего вы ее используете. Первое, что нужно сделать, это оценить, где у вас могут возникнуть проблемы с параллелизмом. То, что вы используете библиотеку в нескольких потоках, не означает, что ее нельзя использовать в нескольких потоках. Посмотрите на элементы в API, которые конкретно говорят: «Это не потокобезопасно», и если вы будете использовать эту часть API, вам нужно будет синхронизировать ее самостоятельно. Самое простое решение - создать класс-оболочку, который синхронизирует все методы. Для примера посмотрите на источник из утилит сбора (таких как Collections.synchronizedList и т. Д.).

2 голосов
/ 23 марта 2010

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

Но когда вам нужна многопоточная коллекция, вы просто получаете ее с

Collections.synchronizedCollection(unsafeCollection)

Реализация скрыта от пользователя и не является частью API. Вы можете пойти по тому же пути.

2 голосов
/ 23 марта 2010

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

Иногда альтернативой может быть использование отдельных экземпляров объектов библиотеки для каждого потока. Но в этом случае экземпляры не могут быть разделены между потоками.

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