Jelenleg egy szervert írok, amelyhez több kliens fog csatlakozni. A kommunikációs protokoll alapvetően abból áll, hogy a szerver küld egy feladatot a klienseknek, és a kliensek válaszolnak a feladat végrehajtására. Az ügyfelek továbbra is kapcsolatban maradnak a szerverrel, és soha nem szakíthatják meg a kapcsolatot.
Jelenleg egy új szálat indítok az egyes ügyfelek kezelésére. Lélekben a jelenlegi megoldásom a következő: (forrás: Java párhuzamosság a gyakorlatban)
public class ThreadPerTaskWebServer {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
Runnable task = new Runnable() {
public void run() {
handleRequest(connection);
}
};
new Thread(task).start();
}
}
private static void handleRequest(Socket connection) {
// request-handling logic here
}
}
De szeretném az Executorokat használni, mert stabilabbnak és jobban skálázhatónak tűnnek. Tehát ahhoz, hogy a szerver tudjon üzeneteket küldeni a klienseknek, külön kell nyomon követnem a klienseket az őket futtató végrehajtótól. Tehát ha hova helyezhetem el az ügyfeleket a CopyOnWriteArrayList kliensekben, és van valami ilyesmi a Server osztályban:
Socket clientSocket = serverSocket.accept();
// The runnable that takes care of a client
ClientHandler c = new ClientHandler(clientSocket, this);
// Start executing the ClientHandler
exec.execute(c);
// Add clients to CopyOnWriteArrayList
clients.add(c);
Ez lehetővé tenné, hogy a CopyOnWriteArrayList-en át ismételjem, hogy parancsokat küldjek az összes kliensnek, és eltávolítsam a leválasztottakat is. Ez robusztus megoldás lenne? Mi történne a végrehajtóval, ha egy futtatható valamilyen okból kivételt hirdetne rá?