I currently have code that is working but I think it can be optimised. The code waits until a player joins and adds the player to a BlockingQueue if there is not already a Player waiting then it starts a game. The code also allows for multiple games to be played at the same time. The Players are two different threads that need to get the same answer about the game outcome.
PlayerQueue
import java.util.concurrent.*;
public class PlayerQueue {
private final BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(1);
private final ConcurrentMap<String, String> userIdToResponse = new ConcurrentHashMap<>();
public String battle(String user) {
String opponent = null;
try {
boolean stopLoop = false;
while (!stopLoop) {
if (blockingQueue.remainingCapacity() > 0) {
stopLoop = blockingQueue.offer(user, 1, TimeUnit.SECONDS);
} else {
opponent = blockingQueue.poll(500, TimeUnit.MILLISECONDS);
if (opponent != null) {
System.out.println("starting game");
String outcome = match(user, opponent);
userIdToResponse.put(opponent, outcome);
return outcome;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
return "SOMETHING WENT WRONG";
}
if (opponent == null) {
while (!userIdToResponse.containsKey(user)) {
}
return userIdToResponse.get(user);
}
return "ERROR";
}
private String match(String user1, String user2) {
return user1 + " vs. " + user2;
}
}
Main
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
PlayerQueue playerQueue = new PlayerQueue();
Executor executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; ++i) {
String user = "user" + Integer.toString(i);
executor.execute(() -> System.out.println(playerQueue.battle(user)));
}
}
}
Step-by-Step Game Example:
- Player 1 Thread calls the battle and passes the User its user instance which will be stored in the Queue
- Player 2 Thread calls the battle since there is a player in the queue it starts a game
- The game ends the Player 2 Thread puts the Game result into the Map
- Player 1 Thread finds their User.id in the map gets the response and returns to the Response to the thread
Concerns:
- Infinity while loop on the map and no possibility to stop thread 1
- Overall performance because of the while loop