Я разрабатываю сетевую игру для двух игроков, в которой пользователи играют, отправляя данные через веб-сокет, с сервером Spring Boot, обрабатывающим игровые события.
Перед началом игры пользователь отправляет запрос на запуск игра со случайным противником, и мне нужно как-то сопоставить два таких запроса, которые могут обрабатываться разными потоками. Я попытался реализовать сопоставление игр, используя SynchronousQueue
: сначала я пытаюсь предложить себя кому-то, ожидающему партнера, и если это не удается, я начинаю ждать партнера в надежде, что кто-то появится. Что меня беспокоит, так это то, что если я предложу себя и начну ждать, кто-то другой попытается предложить себя, потерпит неудачу, и мы оба начнем ждать, даже если бы мы могли совпасть. Вот код для моего @Service
, выполняющего соответствующую работу:
private SynchronousQueue<WebSocketSession> queue = new SynchronousQueue<>();
...
@Override
public void startGame(WebSocketSession me) {
try {
// offer us to somebody waiting
if (!queue.offer(me)) {
// Q: can someone from a different thread attempt and fail offering while I am here?
// there was nobody waiting, we'll wait for someone
WebSocketSession opponent = queue.poll(MAX_WAIT_TO_FIND_OPPONENT.toMillis(), TimeUnit.MILLISECONDS);
if (opponent == null) {
// we found nobody within time limit
sendNoOpponentMessage(me);
return;
}
createGame(me, opponent);
}
} catch (InterruptedException e) {
sendNoOpponentMessage(me);
}
}
Если это возможно и представляет проблему, как бы я успешно совпал с двумя игроками, вызывающими этот метод одновременно?