При использовании параллелизма всегда сложно дать хорошие ответы.Это сильно зависит от того, что вы действительно делаете и что действительно важно.
Насколько я понимаю, ход игрока включает в себя:
1 Обновление позиции игрока.
2 Удаление игрокас предыдущего поля.
3 Добавление игрока на новое поле.
Представьте, что вы используете несколько замков одновременно, но приобретаете только по одному за раз: - Другой игрок может отлично смотреть в неподходящий моментв основном между 1 и 2 или 2 и 3.Может показаться, что некоторые игроки исчезли с игрового поля в качестве примера.
Представьте, что вы заблокировали блокировку так:
synchronized(player) {
synchronized(previousField) {
synchronized(nextField) {
...
}
}
}
Проблема в том, что ... это не работает, посмотрите на этопорядок выполнения для 2 потоков:
Thread1 :
Lock player1
Lock previousField
Thread2 :
Lock nextField and see that player1 is not in nextField.
Try to lock previousField and so way for Thread1 to release it.
Thread1 :
Lock nextField
Remove player1 from previous field and add it to next field.
Release all locks
Thread 2 :
Aquire Lock on previous field and read it :
Поток 2 считает, что player1 исчез из всей доски. Если это проблема для вашего приложения, вы не можете использовать это решение.
Дополнительная проблема для блокировки блокировки: резьба может застрять.Представьте себе 2 игроков: они обмениваются своими позициями в одно и то же время:
player1 aquire it's own position at the same time
player2 aquire it's own position at the same time
player1 try to acquire player2 position : wait for lock on player2 position.
player2 try to acquire player1 position : wait for lock on player1 position.
=> Оба игрока заблокированы.
Лучшее решение, на мой взгляд, это использовать только один замок длявсе состояние игры.
Когда игрок хочет прочитать состояние, он блокирует все состояние игры (игроки и доска) и делает копию для собственного использования.Затем он может обрабатываться без какой-либо блокировки.
Когда игрок хочет записать состояние, он блокирует все игровое состояние, записывает новое состояние и затем снимает блокировку.
=> Блокировкаограничено операциями чтения / записи игрового состояния.Игрок может выполнить «длинную» проверку состояния доски на своей собственной копии.
Это предотвратит любое несовместимое состояние, например, игрок на нескольких полях или нет, но не помешает этому игроку использовать «старое» состояние..
Это может показаться странным, но это типичный случай шахматной игры.Когда вы ждете, чтобы другой игрок двинулся, вы видите доску как перед ходом.Вы не знаете, какой ход сделает другой игрок, и пока он, наконец, не двинется, вы работаете в «старом» состоянии.