【问题标题】:Problem with cleaning up a thread pool清理线程池的问题
【发布时间】:2011-06-10 15:24:08
【问题描述】:

我有一个多线程的 Java 服务器,我已经为它创建了一个线程池。 现在一切顺利,我的服务器接受并从连接到它的客户端读取数据,但我真的不知道如何在连接关闭后清理套接字。

这是我的代码:

public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub

    ThreadPooledServer server = new ThreadPooledServer(queue,7001);
    new Thread(server).start();
}

ThreadPooledServer 类:

public class ThreadPooledServer implements Runnable {
    protected ExecutorService threadPool = Executors.newFixedThreadPool(5);

public ThreadPooledServer(BlockingQueue queue,int port) {
    this.serverPort = port;
    this.queue=queue;
}

    public void run() {
        openServerSocket();

        while (!isStopped()) {
            Socket clientSocket = null;
            try {
                clientSocket = serverSocket.accept();
                clientconnection++;
            } catch (IOException e) {
                if (isStopped()) {
                    System.out.println("Server Stopped.");
        return;
            }

            throw new RuntimeException("Error accepting client connection", e);
        }

        WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);

        this.threadPool.execute(workerRunnable);

    }
    this.threadPool.shutdown();

    System.out.println("Server Stopped.");
}

private synchronized boolean isStopped() {
    return this.isStopped;
}

public synchronized void stop() {
    this.isStopped = true;

    try {
        this.serverSocket.close();
    }

    catch (IOException e) {
        throw new RuntimeException("Error closing server", e);
    }
}

以下是我不明白的地方:我的 while() 循环接受客户端的工作时间与 isStopped 一样长。

isStopped 设置为 true 时,我的循环结束,然后我关闭了我的线程池,这是正确的。

isStopped 在 onstop(){.......}....中设置为 true。

我应该在哪里调用 onstop()...?

因为此时我没有使用这个方法,所以我没有调用它,这意味着我没有正确清理我的线程。

WorkerRunnable 类:

    public class WorkerRunnable implements Runnable {
        public WorkerRunnable(BlockingQueue queue2, Socket clientSocket2) {
        // TODO Auto-generated constructor stub

            this.clientSocket2 = clientSocket2;

            this.queue2 = queue2;
        }

        public void run() {
            try {
                is = new ObjectInputStream(this.clientSocket2.getInputStream());

                try {
                    while (!stop) {
                        System.out.println("Suntem in interiorul buclei while:!");

                        v = (Coordinate) is.readObject();

                        queue2.put(v);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    is.close();

                    clientSocket2.close();
                }

                is.close();
                clientSocket2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void stop() {
            this.stop = true;
        }
    }
}

在这里我有同样的问题。我应该如何正确清理和关闭我的套接字?

【问题讨论】:

  • -1,你有 65 个代表,你现在应该知道如何在 SO 上格式化代码块了。
  • 感谢你,我现在有 63 个!
  • @george,现在为打翻的牛奶哭已经太迟了。我代表您编辑了您的帖子。
  • 实际上,自从我发表评论试图改进您的帖子以来,我已经花了整整 10 分钟。我不只是做一个简单的 CTRL + K;我清理了未对齐的大括号、间距问题、语法问题和其他问题。但我看得出你不想让我在这里,所以我会离开。
  • @Lord Torgamus,你真的是-1吗?让他休息一下,他至少尝试过正确格式化它。

标签: java multithreading sockets


【解决方案1】:

一旦您调用shutdown(),线程池将在所有任务完成后关闭每个线程。

您应该从任何知道池应该关闭的代码中调用onstop()。这取决于您的应用程序的其余部分做什么,以及您为什么要在应用程序完成之前停止池。

【讨论】:

  • 该方法称为 stop()....但我认为我应该在我的应用程序关闭时调用它,这样我就可以关闭所有工作线程!另一个问题是在 WorkerRunnable我使用相同的技术....当出现异常或我的套接字的另一端已关闭时,我应该关闭我的 WorkerRunnable!!!!我该怎么做?
  • 退出时为什么需要关闭线程/socket?当您退出时,它们无论如何都会停止/关闭。当另一端关闭时,您会收到一个异常,您可以捕获并关闭套接字。 (你似乎已经在做)
  • 所以 stop() 方法在这一切中都没有作用???:-S....我应该在这段代码中改进什么?:-S
  • 如果您希望客户端正常关闭其连接,则关闭非常有用。但是,客户端应该始终假设连接可能会突然丢失。
  • 我会使用标准日志记录和实用程序方法来处理 close(),例如 Apache commons IOUtils.close(),这将简化您的一些代码并确保您正确关闭。我不会读取您的数据并将其放置在队列中,我只会在同一个线程中处理对象以简化您的解决方案(无论如何,Socket 是一种队列)您可能希望确保您的 ObjectOutputSTream 定期调用 reset()防止内存泄漏。 (否则两端都会记住他们见过的每一个物体,随着时间的推移会不断增长)
猜你喜欢
  • 2020-10-02
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多