如何实现 Java Socket 线程池

1. 流程概览

在开始教会小白如何实现 Java Socket 线程池之前,先让我们了解一下整个流程。以下是实现 Java Socket 线程池的基本步骤:

步骤 描述
1 创建一个 ServerSocket 对象,绑定指定的端口号,并监听该端口。
2 创建一个线程池,用于处理客户端的连接请求。
3 等待客户端连接请求,并将请求交给线程池中的空闲线程进行处理。
4 在线程池中的线程中处理客户端请求,并返回相应的响应结果。
5 关闭连接。

接下来,让我们逐步介绍每一步需要做什么以及需要使用的代码。

2. 代码实现

步骤 1:创建 ServerSocket 对象

import java.io.IOException;
import java.net.ServerSocket;

public class SocketServer {

    public static void main(String[] args) {
        int port = 8080; // 指定监听的端口号

        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Server listening on port " + port);
            
            // TODO: 此处需要将 serverSocket 对象传递给线程池进行处理

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们通过 ServerSocket 类的构造函数创建了一个 serverSocket 对象,并绑定了指定的端口号。此时,服务器已经开始监听该端口。

步骤 2:创建线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SocketServer {

    public static void main(String[] args) {
        int port = 8080;

        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Server listening on port " + port);

            ExecutorService executor = Executors.newFixedThreadPool(10);
            
            // TODO: 此处需要将 serverSocket 对象传递给线程池进行处理

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们使用 Executors 类的 newFixedThreadPool 方法创建了一个固定大小的线程池(此处为10个线程)。这个线程池将用于处理客户端的连接请求。

步骤 3:等待客户端连接请求

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    public static void main(String[] args) {
        int port = 8080;

        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Server listening on port " + port);

            ExecutorService executor = Executors.newFixedThreadPool(10);
            
            while (true) {
                Socket clientSocket = serverSocket.accept();
                executor.execute(new SocketHandler(clientSocket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们使用 accept 方法等待客户端的连接请求。一旦有客户端连接请求到达,该方法将返回一个新的 Socket 对象,用于与客户端进行通信。然后,我们将这个 Socket 对象传递给线程池中的一个空闲线程进行处理。

步骤 4:处理客户端请求

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class SocketHandler implements Runnable {

    private final Socket clientSocket;

    public SocketHandler(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);

            String request = reader.readLine();
            
            // TODO: 在此处处理客户端的请求,并返回相应的响应结果

            writer.close();
            reader.close();
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们创建了一个 SocketHandler 类,实现了 Runnable 接口,用于处理客户端的请求。在 run 方法中,我们通过输入流和输出流与客户端进行通信,