๐ฎ Online Matchmaking (Real-Time Queue Handling) Concurrency Problem


Problem
Simulate an online matchmaking system where:
Players join a matchmaking queue in real-time.
When enough players are available (say, 4 or 10), a match is created.
Players are then removed from the queue, and a game session is started.
Solution Approaches
Naive / Basic Implementation
we just keep a normal list of players waiting for a match.
import java.util.*;
public class NaiveMatchmaking {
static final int PLAYERS_PER_MATCH = 4;
static List<Integer> waitingPlayers = new ArrayList<>();
public static void main(String[] args) {
// Players joining (simulated)
for (int i = 1; i <= 8; i++) {
joinQueue(i);
}
}
static void joinQueue(int playerId) {
waitingPlayers.add(playerId);
System.out.println("๐ Player #" + playerId + " joined queue.");
if (waitingPlayers.size() >= PLAYERS_PER_MATCH) {
startMatch();
}
}
static void startMatch() {
List<Integer> matchPlayers = waitingPlayers.subList(0, PLAYERS_PER_MATCH);
System.out.println("๐ฎ Match started: " + matchPlayers);
matchPlayers.clear(); // remove them from queue
}
}
Problem โ Concurrency Breaks This
Now, in real life:
Players join in parallel (multiple threads)
Matches are formed in real-time
The list
waitingPlayers
is not thread-safe โ Race conditions happen:Two threads may see enough players and start the same match twice.
Players may be skipped or duplicated.
Modifying the same list from multiple threads โ
ConcurrentModificationException
.
Example failure scenario:
Thread 1: sees 4 players โ starting match...
Thread 2: sees same 4 players โ starting another match...
โ First Fix โ Add Locks (synchronized
)
try to fix it by synchronizing the join method.
static synchronized void joinQueue(int playerId) {
waitingPlayers.add(playerId);
if (waitingPlayers.size() >= PLAYERS_PER_MATCH) {
startMatch();
}
}
static synchronized void startMatch() {
List<Integer> matchPlayers = new ArrayList<>(waitingPlayers.subList(0, PLAYERS_PER_MATCH));
System.out.println("๐ฎ Match started: " + matchPlayers);
waitingPlayers.removeAll(matchPlayers);
}
โ
This works for correctness.
โ But:
It blocks all player joins when one player is joining or a match is starting โ slower.
If you scale to thousands of players, this becomes a bottleneck.
Better Approach
will be covered in our course.
Subscribe to my newsletter
Read articles from Subhahu Jain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
