【问题标题】:Java server structureJava服务器结构
【发布时间】:2014-05-01 06:14:12
【问题描述】:

目前我的 java 服务器工作正常,将所有客户端存储在一个新线程上,但性能不是很好。

我的 MainServer 类

public class MainServer {

    private ServerSocket server;

    public MainServer(int port) {

        try {

            server = new ServerSocket(port);
            System.out.println("Server started on port " + port + "...");
            ServerLoop();

        } catch (IOException e) {

            System.out.println("[ERROR] Server cannot be started on port " + port + "...");
        }
    }

    public void ServerLoop() {

        Thread serverLoop = new Thread(new Runnable() {

            public void run() {

                ServerDispatcher dispatcher = new ServerDispatcher();

                while (true) {

                    try {

                        Socket connectedClient = server.accept();
                        dispatcher.connectedClients.add(connectedClient);
                        System.out.println("Client number - " + dispatcher.connectedClients.size() + " connected...");
                        Thread clientThread = new Thread(new ClientHandler(connectedClient, dispatcher));
                        clientThread.start();

                    } catch (IOException e) {

                        e.printStackTrace();
                    }
                }
            }
        });

        serverLoop.start();
    }
}

所以这部分将为每个客户端启动一个新线程,并将客户端添加到调度程序客户端列表中

ClientHandler 类

public class ClientHandler implements Runnable {

    private Socket currentClient;
    private ServerDispatcher handler;

    public ClientHandler(Socket s, ServerDispatcher dispatcher) {

        currentClient = s;
        handler = dispatcher;
    }

    public void run() {



        while (true) {


        }


    }
}

这是我的 ServerDispatcher 类

public class ServerDispatcher {

    public ArrayList<Socket> connectedClients;

    public ServerDispatcher() {

        connectedClients = new ArrayList<Socket>();
        CheckClients();
    }

    public void CheckClients() {

        Thread checkClients = new Thread(new Runnable() {

            public void run() {

                while (true) {

                    Integer clientSize = connectedClients.size();

                    if (!clientSize.equals(0)) {

                        for (int i = 0; i < connectedClients.size(); i++) {

                            try {

                                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connectedClients.get(i).getOutputStream()));
                                writer.write("1");
                                writer.flush();
                                //System.out.println("Checking");

                            } catch (IOException e) {

                                int clientNumber = i + 1;
                                System.out.println("Client number - " + clientNumber + " disconnected...");
                                connectedClients.remove(i);
                            }
                        }
                    }
                }
            }
        });

        checkClients.start();
    }
}

这会检查所有在线客户...

问题是这台服务器在执行时使用了大约 67% 的 CPU,我该如何改进代码?也许从 ServerDispatcher 中删除所有线程并离开客户端线程?

还有一个问题:我想在我的 while 循环中向 X 客户端发送一条消息,但只是有一次,我查看了谷歌,似乎 LinkedBlockingQueue 是我正在寻找的,但我找不到任何简单的教程实施..

【问题讨论】:

  • while (true) { } 是什么原因造成的?
  • 好吧,我认为我真的需要同时保持服务器上的客户端连接处于活动状态,(不是吗?)
  • TCP 协议使连接保持活动状态,您无需发送任何内容。

标签: java multithreading sockets


【解决方案1】:

您的循环只是尽可能快地发送数据,而当它不能发送数据时则忙着等待。这必然会使用大量的 CPU。一个简单的解决方案是只定期发送虚拟数据(因为它根本不需要发送)

我建议添加

Thread.sleep(100);

到发送循环,你的 CPU 应该下降到 1% 左右。

您还可以进行许多其他改进,但没有一个比这更重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多