Использовать темы как "сеансы" - PullRequest
0 голосов
/ 26 января 2012

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

В моей игре мне нужно хранить информацию, такую ​​как текущее положение или очки здоровья для каждого игрока.Я мог бы держать его в базе данных, но, поскольку он будет меняться очень быстро, иногда каждую секунду, использование базы данных будет неэффективным (я прав?).

Мой вопрос: могут ли потоки вести себя как «сеансы»?", т.е. держать какие-то данные, уникальные для каждого пользователя?

Если да, не могли бы вы направить меня к некоторым ресурсам, которые я мог бы использовать, чтобы помочь мне понять, как это работает?

Если нет, что вы предлагаете?Является ли база данных хорошим вариантом или вы бы порекомендовали что-то еще?

Cheers, Eleeist

Ответы [ 5 ]

5 голосов
/ 26 января 2012

Да, они могут, но это ошеломительно глупый способ делать вещи.С одной стороны, он навсегда блокирует модель «один поток на клиента».С другой стороны, это затрудняет (может быть, даже невозможно) взаимодействие между пользователями, что, я уверен, в вашем MUD.

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

Один из способов справиться с этим - иметь «измененное» логическое значение для каждого пользователя.Когда вы вносите критические изменения в пользователя, немедленно записывайте их в базу данных.Но если это обычное некритическое изменение, просто установите флаг «изменено».Затем каждый раз приходите к потоку и записывайте измененных пользователей в базу данных (и снимайте флажок «изменено»).

Конечно, используйте соответствующую синхронизацию!

4 голосов
/ 26 января 2012

Поток на соединение / пользовательский сеанс не масштабируется. Вы можете иметь только N активных потоков, где N равно числу физических ядер / процессоров, которые есть на вашей машине. Вы также ограничены объемом памяти на вашей машине, сколько потоков вы можете создать за время, некоторые операционные системы просто устанавливают произвольные ограничения .

Нет ничего волшебного в Threads при работе с несколькими клиентами. Они просто сделают ваш код более сложным и менее детерминированным и, следовательно, сложнее рассуждать о том, что на самом деле происходит, когда вы начинаете искать логические ошибки.

Поток на соединение / пользовательский сеанс будет анти-шаблоном !

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

Посмотрите на одновременные карты для кэширования (или используйте какое-нибудь подходящее решение для кэширования) и обработайте их, а затем сделайте что-нибудь еще. См. java.util.concurrent для всех примитивных классов, которые вам нужны для правильной реализации.

1 голос
/ 26 января 2012

Вместо того, чтобы беспокоиться о потоках и их безопасности, я бы использовал базу данных SQL в памяти, такую ​​как HSQLDB , для хранения информации о сеансе. Среди других преимуществ, если ваш MUD окажется следующей Angry Birds, вы могли бы легко увеличить масштаб.

1 голос
/ 26 января 2012

ThreadLocal ваш друг! :)

http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

ThreadLocal обеспечивает хранение в самой теме. Таким образом, один и тот же вызов из двух разных потоков вернет / сохранит разные данные.

Самая большая опасность - утечка между нитями. Вы должны быть абсолютно уверены, что если бы другой пользователь использовал поток, который использовал кто-то другой, вы бы сбросили / очистили данные.

0 голосов
/ 26 января 2012

Определенно, вы можете использовать потоки в качестве сеансов. Но это немного не так.

Основным моментом потоков является возможность одновременного асинхронного выполнения. Скорее всего, вы не хотите, чтобы события, полученные от ваших клиентов MUD, происходили в параллельном, неконтролируемом порядке.

Чтобы обеспечить целостность мира, я бы использовал базу данных в памяти для хранения игрового мира. Я бы сериализовал обновления к нему, или, по крайней мере, некоторые обновления к нему. Представьте, что два игрока параллельно бьют монстра с HP 100. Каждый наносит 100 урона. Если вы не сериализуете обновления, вы можете в итоге дать 100 очков урона обоим игрокам. Представьте двух игроков, одновременно получающих добычу от монстра. Без надлежащей сериализации у них может быть своя копия лута.

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

...