Java streams not output

I am trying to implement a really simple multi-threaded echo-back server.
I used a thread pool created using newFixedThreadPool, but it looks like the number of concurrent connections is fixed at nThreads(passed to newFixedThreadPool). For example, if I set nThreadsto 3, then the fourth client that connects cannot communicate with the server.

This is rather strange because the documentation says: "Creates a pool of threads in which it reuses a fixed number of threads working with a common unlimited queue."
Because the documentation also says that "If additional tasks are transferred when all threads are active, they will wait in line until the thread is available." I suspect my threads are never "freed", so they never become reusable.

I think this may be a stupid mistake, but I could not understand what happened. Here is my client handler method run(), which, I think, is very similar to the code found here ( clientbelow - it is just Socketconnected to the client):

@Override
public void run() {
    try(BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {

        String input;
        while(true) {
            input = readLine();
            if(input == null)
                break;

            out.write(input);
            out.newLine();
            out.flush();
        }
    } catch(IOException e) {
        System.err.println(e, "Error from socket IO.");
        System.exit(1);
    }

    try {
        client.close();
    } catch(IOException e) {
        System.err.println(e, "Error when closing socket.");
        System.exit(1);
    }
    System.out.println("Client " + client.getInetAddress().getHostAddress() +
                        " closed connection.\n");
}

1: , , . .

EDIT 2: , (listen - ServerSocket):

while(true) {
    Socket client = null;
    try {
        client = listen.accept();
    } catch(IOException e) {
        System.err.println(e, "Error when waiting for connection.");
        System.exit(1);
    }
    System.out.println("New connection from client: " +
            client.getInetAddress().getHostAddress() + "\n"
    );

    threadPool.execute(new ConnectionHandler(client));
}

( ): this.threadPool = Executors.newCachedThreadPool();.

3: ( nThread = 3, ):

New connection from client: 127.0.0.1

Client 127.0.0.1 closed connection.

New connection from client: 127.0.0.1

Client 127.0.0.1 closed connection.

New connection from client: 127.0.0.1

Client 127.0.0.1 closed connection.

New connection from client: 127.0.0.1
+6
2

, , , , ...

public class Test {
    public static void main(String[] args) throws Exception {
        ServerSocket listen = new ServerSocket(9999);
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        while(true) {
            Socket client = null;
            try {
                client = listen.accept();
            } catch(IOException e) {
                System.err.println(e);
            }
            System.out.println("New connection from client: " +
                    client.getInetAddress().getHostAddress() + "\n"
            );

            threadPool.execute(new ConnectionHandler(client));
        }
    }
}

class ConnectionHandler implements Runnable {
    private Socket client;

    public ConnectionHandler(Socket client) {
        this.client = client;
    }

    @Override
    public void run() {
        try(BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {

            String input;
            while(true) {
                input = in.readLine();
                if(input == null)
                    break;

                out.write(input);
                out.newLine();
                out.flush();
            }
        } catch(IOException e) {
            System.err.println("Error from socket IO.");
        }

        try {
            client.close();
        } catch(IOException e) {
            System.err.println("Error when closing socket.");
        }
        System.out.println("Client " + client.getInetAddress().getHostAddress() +
                " closed connection.\n");
    }
}

telnet, . 5 .

    New connection from client: 0:0:0:0:0:0:0:1

    Client 0:0:0:0:0:0:0:1 closed connection.

    New connection from client: 0:0:0:0:0:0:0:1

    Client 0:0:0:0:0:0:0:1 closed connection.

    New connection from client: 0:0:0:0:0:0:0:1

    Client 0:0:0:0:0:0:0:1 closed connection.

    New connection from client: 0:0:0:0:0:0:0:1

    Client 0:0:0:0:0:0:0:1 closed connection.

    New connection from client: 0:0:0:0:0:0:0:1

    Client 0:0:0:0:0:0:0:1 closed connection.

, ...

input = readLine();

input = in.readLine();

. , , , - .

+2

, ( ).

, "exit", InputHandler ( Runnable) . :

class InputHandler implements Runnable {
    private Server server;

    InputHandler(Server server) {
        this.server = server;
    }

    @Override
    public void run() {
        String input = System.console().readLine();
        if(input.toLowerCase().equals("exit"))
            server.shutdown();
        else
            System.err.println("Invalid command. To exit enter \"exit\".");
    }
}

run() :

private void loop() {
    while(true) {
        threadPool.execute(new InputHandler(this));

        Socket client = null;
        try {
            client = listen.accept();
        } catch(Exception e) {
            System.err.println("Error when waiting for connection.");
            System.exit(1);
        }
        System.out.println("New connection from client: " +
            client.getInetAddress().getHostAddress() + "\n"
        );

        threadPool.execute(new Handler(client));
    }
}

InputHandler... (threadPool.execute(new InputHandler(this));). ...

InputHandler, . , .

, , . . , : down . slipperyseal . .

+2

All Articles