Жду игру подключение к серверу


public boolean connectedOnGameServer = false;
public final Object conGameServerMonitor = new Object();

public void connectedToGameServer() {
    synchronized (conGameServerMonitor) {
        if (connectedOnGameServer != false)
            throw new RuntimeException("Player connected twice");
        connectedOnGameServer = true;
        conGameServerMonitor.notifyAll();
    }
}

public void waitForGameServerConnection() {
    synchronized (conGameServerMonitor) {
        try {
            long startTime = System.currentTimeMillis();
            long waited = 0;
            while (!connectedOnGameServer && waited < GAMESERVER_CONNECT_TIMEOUT) {
                conGameServerMonitor.wait(GAMESERVER_CONNECT_TIMEOUT - waited);
                waited = System.currentTimeMillis() - startTime;
            }
            if (waited > GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer) {
                throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while waiting for client to connect to game server", e);
        }
    }
}

Что мне нужно:

  • Поток звонков waitForGameServerConnection
  • Поток B вызывает connectedToGameServer
  • Нить продолжается


Комментарии
1 ответ

Мои примеры кода приведены выдержки. Не копируйте их, их предложения вы можете включить в свой код.

if (waited > GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer)
{
throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}

можно сократить до:

if (!connectedOnServer) {
throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}

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

public boolean waitForConnection() {
synchronized (conGameServerMonitor) {
// loop, guard
return connectedOnGameServer? true : false;
}
}

При этом вы можете задать игрока, если он хочет попробовать еще раз, или подождать немного и снова попробовать, и т. д. без того, чтобы поймать исключение.
Но что, если б звонки connectedToGameServer() после ожидания завершения?

boolean connectionInProgress;

public void connectedToGame() {
synchronized (conGameServerMonitor) {
if (connectionInProgress) {
connectedOnGameServer = true;
conGameServerMonitor.notifyAll();
}
}
}

public boolean waitForConnection() {
synchronized (conGameServerMonitor) {
connectionInProgress = true;
// wait
connectionInProgress = false;
return connectedOnGameServer? true : false;
}
}

Вы ведет себя корректно пробуждения и перебоев в работе. Респект ждал часть - я думал, "бесполезно!" на секунду, но я забыл, что поток может проснуться в любое время, и это что-нить ответственность, чтобы убедиться, что его условия будут выполнены.

6
ответ дан 8 февраля 2011 в 03:02 Источник Поделиться