TCP ThreadPool(地址已在使用中)

时间:2014-01-18 23:30:32

标签: java sockets tcp threadpool

美好的一天,

我已经实现了一个线程池,它接收一个Runnable对象。基本上,我正在构建一个必须处理请求的简单服务器实现。以下代码:

public static void main(String[] args) {

    // Assign your no. of thread to create 
    int noOfProcess = 5; 
    // Assign your own thread pool size
    int poolMaxSize = 2;

    // Creating Threadpool with the thread size given above
    MyThreadPool threadPool = new MyThreadPool(poolMaxSize);
    // Creating threadpool Object
    ThreadPoolTester obj = new ThreadPoolTester();

    for (int i = 0; i < noOfProcess; i++) {
        threadPool.process(obj.startProcess(i));
    }

    // Finally waiting for all thread to complete its process
    threadPool.join();
}

private Runnable startProcess(final int taskID) {
    return new Runnable() {
        public void run() {
            System.out.println("Task " + taskID + ": start");

            ServerSocket server;
            try {
                server = new ServerSocket(8080);
                while (true) {
                    final Socket connection = server.accept();
                    handle(connection);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.out.println("Task " + taskID + ": end");
        }
    };
}

基本上,当我只有一个线程插入到线程池中时,这应该可行。但是,一旦我有两个或更多,就会抛出绑定异常。

我想知道的是,处理这个问题的正确方法是什么?服务器通常如何做到这一点?您是否只捕获异常,并继续循环直到线程完成任务?有没有办法让线程睡眠,直到它可以接受?

我如何让5个客户同时发出请求,实际的工作流程是什么?

1 个答案:

答案 0 :(得分:1)

以下行创建ServerSocket并将其绑定到端口8080

server = new ServerSocket(8080);

Runnable内部执行此操作时,如果使用多个线程,则会为同一端口创建多个ServerSockets!这就是你得到异常的原因 - 端口已经在使用中。

如果要并行处理多个客户端请求,则无需创建多个ServerSockets。在handle方法中使用线程池:

public static void main(String[] args) throws Exception
    // Creating Threadpool with the thread size given above
    ExecutorService executor = Executors.newFixedThreadPool(5);

    ServerSocket server = new ServerSocket(8080);
    while (true) {
        Socket socket = server.accept();
        handleAsync(executor, socket);
    }
}

private void handleAsync(ExecutorService executor, final Socket socket) {
    executor.execute(new Runnable() {
        public void run() {
            handle(socket);
        }
    };
}

private static void handle(Socket socket) {
    // TODO: communicate with client using socket
}

另请参阅ExecutorService了解另一个服务器示例。 来自Thread Pooled Server的另一个turial是Jakob Jenkov