Ответ 1
Обычно я использую N + 1 потоков для этого: один для ServerSocket, чтобы избежать блокировки всего приложения, ожидающего подключения клиента; и N потоков для обработки клиентских запросов, N - размер пула потоков (я рекомендую использовать пул потоков для создания нового потока для каждого клиента).
Вот пример (только что закодированный, вы можете иметь лучшее управление исключениями и т.д., но это минимальный рабочий пример)
public class Server {
public static void main(String[] args) {
new Server().startServer();
}
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
System.out.println("Got a client !");
// Do whatever required to process the client request
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}