Параллелизм / синхронизация сервлетов в Tomcat? - PullRequest
3 голосов
/ 07 октября 2009

Есть ли рекомендуемый способ синхронизации экземпляров сервлета Tomcat, которые конкурируют за один и тот же ресурс (например, файл или базу данных, например MongoDB, которая не является ACID)?

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

edit: у меня работает только 1 сервер Tomcat. Независимо от того, означает ли это разные JVM или нет, я не уверен (я предполагаю, что это та же самая JVM, но потенциально разные потоки).


edit: конкретный вариант использования (но я задаю вопрос в целом):

Сервер Tomcat действует как хранилище файлов, помещая необработанные файлы в каталог и используя MongoDB для хранения метаданных. Это довольно простая концепция, за исключением проблемы параллелизма. Если есть два одновременных запроса на сохранение одного и того же файла или управление метаданными для одного и того же объекта в одно и то же время, мне нужен способ решить эту проблему, и я не уверен, как это сделать. Я полагаю, что самым простым подходом было бы как-то сериализовать / поставить в очередь запросы. Есть ли способ реализовать организацию очереди в Tomcat?

Ответы [ 5 ]

3 голосов
/ 09 октября 2009

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

3 голосов
/ 07 октября 2009

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

Тогда для фактического gubbinry, если обычная старая синхронизация не подходит, посмотрите, например, класс Семафор (ссылка на часть учебника / примера, который я написал некоторое время назад, на случай, если это полезно ), что позволяет обрабатывать «пулы» ресурсов.

2 голосов
/ 16 октября 2012

У меня есть 2 случая. Если вы ожидаете получить доступ к общему ресурсу для редактирования файлов в той же JVM, вы можете использовать «синхронизированный» в функции Java. Если разные JVM и другие потоки Java не обращаются к общему ресурсу, вы можете попробовать использовать код блокировки файлов вручную, указав номер приоритета каждого потока в очереди

Для базы данных, я считаю, что нет проблемы параллелизма.

1 голос
/ 09 октября 2009

ИМО, ты напрашиваешься на неприятности. Есть причины, по которым были изобретены такие вещи, как базы данных и общие файловые системы. Попытка написать свои собственные, используя какой-то класс или семафор Singleton, станет очень быстро уродливой. Найдите решение для хранения данных, которое сделает это за вас, и избавьте себя от множества головных болей.

1 голос
/ 07 октября 2009

Ваш внешний ресурс будет так или иначе представлен объектом Java (например, java.io.File). Вы всегда можете синхронизировать этот объект, если вам нужно.

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

...