首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Socket 服務端單線程改多線程:一個 ServerSocket + 線程池處理併發客戶端

     編輯:程式設計綜合問答

原始單線程模型缺陷

單線程 accept() → 處理完整會話 → 再 accept(),同一時刻只能服務一個客戶端,後續連接排隊阻塞。

多線程改造核心模式

public class TcpServer {
    private static final int PORT = 12345;
    private static final ExecutorService POOL = Executors.newFixedThreadPool(50);

    public static void main(String[] args) throws IOException {
        try (ServerSocket server = new ServerSocket(PORT)) {
            System.out.println("Server started on " + PORT);
            while (true) {
                Socket client = server.accept(); // 阻塞等待新連接
                POOL.submit(new ClientHandler(client)); // 交給線程池異步處理
            }
        }
    }

    static class ClientHandler implements Runnable {
        private final Socket socket;
        ClientHandler(Socket socket) { this.socket = socket; }

        @Override public void run() {
            try (socket;
                 InputStream in = socket.getInputStream();
                 OutputStream out = socket.getOutputStream()) {

                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) != -1) {
                    // 業務邏輯:反轉字節順序
                    byte[] resp = new byte[len];
                    for (int i = 0; i < len; i++) resp[i] = buf[len - 1 - i];
                    out.write(resp, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客戶端測試代碼(併發驗證)

public class TcpClient {
    public static void main(String[] args) {
        String[] msgs = {"abc", "def", "ghi", "jkl", "mno"};
        for (String msg : msgs) {
            new Thread(() -> {
                try (Socket s = new Socket("localhost", 12345);
                     OutputStream out = s.getOutputStream();
                     InputStream in = s.getInputStream()) {
                    out.write(msg.getBytes());
                    out.flush();
                    byte[] buf = new byte[1024];
                    int len = in.read(buf);
                    System.out.println("Sent: " + msg + " → Recv: " + new String(buf, 0, len));
                } catch (IOException e) { e.printStackTrace(); }
            }).start();
        }
    }
}

關鍵點總結

點說明
ServerSocket 單例全程只需一個 ServerSocket 監聽固定端口
accept() 返回新 Socket每個客戶端連接對應一個獨立 Socket,互不干擾
線程池隔離Executors.newFixedThreadPool 避免無限創建線程 OOM
try-with-resources確保 Socket/流異常時也能關閉,防止句柄洩漏
業務邏輯無狀態Handler 不共享可變狀態,天然線程安全

進階:NIO 非阻塞(Netty)

連接數超過 1 萬時,線程池模型受限於線程上下文切換,建議遷移 Netty:EventLoopGroup + ChannelPipeline 實現高併發低延遲。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved