【问题标题】:Server to process "n" requests from multiple clients concurrently in Java服务器在 Java 中同时处理来自多个客户端的“n”个请求
【发布时间】:2016-05-24 19:55:02
【问题描述】:

我正在用 Java 编写一个 UDP 服务器,它处理来自多个客户端的数据包,然后对其进行处理。我所做的是服务器正在侦听数据包,一旦收到数据包,它就会产生一个新线程来处理它。
以下是示例代码:-

公共无效运行() {

   try
   {
    serverSocket = new DatagramSocket(5676);
    while(true)
    {
        byte[] receiveDataBuf = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveDataBuf,receiveDataBuf.length);
        serverSocket.receive(receivePacket);    
        String sentence  = new String(receiveDataBuf,0,receivePacket.getLength());                  
        ReqHandler  rh= new ReqHandler (sentence);
        rh.start();
    }
    }
    catch(Exception e) 
    {   
    }
}

由于非常频繁地收到客户端请求。问题是当我检查 CPU 百分比时,它占用了 20-30 % {有时高于 30 %}。 我认为这可能是因为 ReqHandler 类处理充当 while(true) 的数据。 我该如何处理?或者是否有任何其他方式来实现可以同时处理“n”个请求的服务器 {concurrently in database} 。

注意:- ReqHandler 正在处理数据库中的数据。

【问题讨论】:

  • 为什么不直接使用 Netty? netty.io
  • 你所做的基本上是如何编写服务器的v1.0。这没有错,这是显而易见的做事方式。这是它的预期问题。线程池(让线程等待并准备好获取数据)是下一步。
  • 正如我在回复@Peter Lawey 的回复时所说,即使在使用 executor service 之后,应用程序使用的 cpu 百分比也很高。那我该如何解决呢?

标签: java multithreading server udp


【解决方案1】:

它产生一个新线程来处理它。

真的很贵。这可能比不创建线程要慢。

另一种方法是使用线程池。

try {
    ExecutorService es = Executors.newCachedThreadPool();
    serverSocket = new DatagramSocket(5676);
    byte[] buf= new byte[1024];
    DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);

    while(serverSocket.isOpen()) {
        serverSocket.receive(receivePacket);
        String sentence  = new String(buf, 0, buf.getLength(), StandardCharsets.UTF_8);
        es.submit(() -> {
             try {
                new ReqHandler (sentence).run();
             } catch (Throwable t) {
                LOG.error("Unable to process " + sentence, t);
             }
         });
    }
} catch(Exception e) {
    LOG.error(e); // don't ignore errors unless you know you can.
}

注意:你的ReqHandler 应该是implements Runnable 而不是extends Thread

【讨论】:

  • 我试过了,但 CPU 百分比仍然很高。但不是写 es.submit(() -> { try { new ReqHandler (sentence).run(); } catch (Throwable t) { LOG.error("Unable to process " + sentence, t); } }) ;我用过 es.submit(new ReqHandler(sentence));
  • @AKT16 在这种情况下,我建议使用 CPU 配置文件来确定使用最多 CPU 的内容。 try/catch 是记录发生的任何错误。如果您不这样做,任何未处理的异常都将被静默丢失。
  • 代码中没有出现这样的错误。正如我所说,这可能是因为我创建了这么多线程来处理客户端请求,这就像 while(true) 一样。因为如果我们在没有 sleep 的情况下使用 while(true) 运行任何程序,程序将消耗更多百分比的 CPU。所以在这里我无法得到我该如何改进呢?
  • 您可以等待阻塞操作,而不是忙于等待。 ExecutorService 等待 BlockingQueue 以防止忙等待。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多