Простая многопоточная Ява петли сервера


Я новичок в розетки и сервера в целом, и я хотел бы знать, если я делаю что-то действительно не так в следующий цикл сервера для нереста потоков для обработки запросов.

private static ServerSocket server;
private static final Object request_counter_lock = new Object();
private static int request_counter = 0;
private static boolean exit = false;

public static void main(String[] args) {
    try {
        server = new ServerSocket(8000,100);
        // Loop until one of the clients sends an exit request.
        while (!exit) {
            try {
                final Socket socket = server.accept();
                // When a connection is accepted we increment the request
                // counter so when the server starts to shut down it waits
                // until all requests are finished processing.
                synchronized(request_counter_lock) { request_counter++; }
                // Fire up a new thread to process requests.
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            processConnection(socket);
                        } catch (IOException e) {
                            logger.error("unable to process request: " + e.getMessage());
                        } finally {
                            // Make sure we close the socket.
                            SocketCloser.close(socket);
                            // Also decrement the request counter because we just closed
                            // the request socket which means we are done with this client.
                            synchronized(request_counter_lock) { request_counter--; }
                        }
                    }
                }).start(); // Fire up the thread.
            } catch (IOException e) {
                logger.error("error accepting socket connection: " + e.getMessage());
            }
        }
    } catch (IOException e) {
        logger.fatal("unable to start server: " + e.getMessage());
    } finally {
        // If the while loop breaks that means we received an exit request from
        // one of the clients but it's possible that there are still some requests
        // in progress so we can't shut down the server right away. We have to wait
        // until the request counter drops down to 0.
        synchronized(request_counter_lock) {
            logger.info("acquired lock for request_counter");
            while(request_counter > 0) {
                logger.info("request counter is above 0 so waiting");
                try {
                    // Wait 1 second for ongoing clients to finish with their work.
                    request_counter_lock.wait(1000);
                } catch (InterruptedException e1) {
                    logger.error("error in request_counter synchronized block: " + e1.getMessage());
                }
            }
        }
        logger.info("request counter reached 0 so going to close server");
        try {
            server.close();
        } catch (IOException e1) {
            logger.error("unable to close server: " + e1.getMessage());
        }
    }
}


Комментарии
1 ответ

Я не рекомендую создавать новые темы самостоятельно или с помощью нитей, не держа на своих ссылках. Это делает его слишком трудно, чтобы закрыть должным образом. В вашем примере, я думаю, что если SocketCloser.рядом(гнездом) бросает, потом request_counter будет один.

Я рекомендую начинать с пулом потоков.

ExecutorService pool = ExecutorService.newCachedThreadPool();

Вы можете использовать фиксированный размер пула, если бесконечный бассейн вызывает проблемы. Затем вы можете представить Runnables в одном месте вы создаете темы, то теперь. Наконец, когда вы хотите закрыть, можно использовать методы shutdownnow не() и awaitTermination() на бассейн.

3
ответ дан 21 июля 2011 в 12:07 Источник Поделиться