patternjavaMinor
Waiting for game server connection
Viewed 0 times
waitinggameforserverconnection
Problem
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 && 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);
}
}
}What I need is:
- Thread A calls
waitForGameServerConnection
- Thread B calls
connectedToGameServer
- Thread A continues
Solution
My code examples are excerpts. Don't copy/paste them, they are suggestions you can incorporate into your code.
can be reduced to:
Now, you can handle this without an exception. Connections fail quite regularly, and it's easy to handle that.
With this you can ask the player if he wants to try again, or wait a bit and try again, etc without having to catch an exception.
But what if B calls
You handle the wakeups and interuptions correctly. Kudos for the
if (waited > GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer)
{
throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}can be reduced to:
if (!connectedOnServer) {
throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}Now, you can handle this without an exception. Connections fail quite regularly, and it's easy to handle that.
public boolean waitForConnection() {
synchronized (conGameServerMonitor) {
// loop, guard
return connectedOnGameServer? true : false;
}
}With this you can ask the player if he wants to try again, or wait a bit and try again, etc without having to catch an exception.
But what if B calls
connectedToGameServer() after the wait completes?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;
}
}You handle the wakeups and interuptions correctly. Kudos for the
waited part - I thought "Useless!" for a second, but I forgot that a thread could wake anytime, and it's the thread's responsibility to be sure that it's conditions are fulfilled.Code Snippets
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;
}
}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;
}
}Context
StackExchange Code Review Q#690, answer score: 6
Revisions (0)
No revisions yet.