简体   繁体   中英

Java application with TCP sockets is using 100% of CPU

The server has to continuously listen for incoming connections and perform some logic on the data received. Every time I run the application, the CPU usage is more than 90%. Earlier I thought that the while loop might be spinning (busy waiting), but the readLine() is supposed to be a blocking call, so I don't think that is the case. Any help is appreciated! The following is the server code:

public void listen() throws IOException
    {

        try( ServerSocket serverSocket = new ServerSocket(port);
             Socket clientSocket = serverSocket.accept();
             DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));)
        {

            String data = null;
            while((data = bufferedReader.readLine()) != null)
            {
                Message message = Message.deserializeMessage(data);
                synchronized (PeerNode.requestHistory)
                {
                    if(PeerNode.requestHistory.keySet().contains(message)) 
                    {
                        continue;
                    }
                }
                if(message.getType() == 0 && message.getHopCount() < 1) {
                    continue;
                }
                switch(message.getType()) {
                    case 0:
                        synchronized (PeerNode.sharedRequestBuffer){ 
                              PeerNode.sharedRequestBuffer.offer(message);
                            }
                        break;
                    case 1:
                        synchronized (PeerNode.sharedReplyBuffer) {
                             PeerNode.sharedReplyBuffer.offer(message);
                        }

                        break;
                    case 2:
                        synchronized (PeerNode.numberOfItems) {
                            if(PeerNode.numberOfItems > 0) {
                                PeerNode.numberOfItems -= 1;
                            }
                            outputStream.writeBytes("0" + "\n");
                        }
                        break;
                }
                synchronized (PeerNode.requestHistory) {
                    PeerNode.requestHistory.put(message, 0);
                }
            }
         }
         catch(Exception ex)
         {
               ex.printStackTrace();
         }
    }

Edit: Added deserialize() method

public static Message deserializeMessage(String s)
    {
        Message m = new Message();
        String[] objArray = s.split("#");
        String[] list = objArray[2].split(",");
        m.setProductName(objArray[0]); 
        m.setProductId(Integer.parseInt(objArray[1]));
        List<Integer> tempList = new ArrayList();
        for(int i=0; i<list.length; i++)
        {
            if(list[i].length() == 0)
                continue;
            tempList.add(Integer.parseInt(list[i]));
        }
        m.setMessagePath(tempList);
        m.setHopCount(Integer.parseInt(objArray[3]));
        m.setType(Integer.parseInt(objArray[4]));
        m.setRequestId(Integer.parseInt(objArray[5]));
        m.setSourcePeerId(Integer.parseInt(objArray[6]));
        m.setDestinationSellerId(Integer.parseInt(objArray[7]));
        m.setDestinationSellerLocation(Integer.parseInt(objArray[8]));
        return m;
    }

Edit 2: Changed deserialize() to use Scanner():

public static Message deserializeMessage(String s)

{
        Message m = new Message();
        Scanner sc = new Scanner(s);
        sc.useDelimiter("#");
        m.setProductName(sc.next());
        m.setProductId(Integer.parseInt(sc.next()));
        List<Integer> tempList = new ArrayList();
        Scanner sct = new Scanner(sc.next());
        sct.useDelimiter(",");
        while(sct.hasNext())
        {
            tempList.add(Integer.parseInt(sct.next()));
        }
        m.setMessagePath(tempList);
        m.setHopCount(Integer.parseInt(sc.next()));
        m.setType(Integer.parseInt(sc.next()));
        m.setRequestId(Integer.parseInt(sc.next()));
        m.setSourcePeerId(Integer.parseInt(sc.next()));
        m.setDestinationSellerId(Integer.parseInt(sc.next()));
        m.setDestinationSellerLocation(Integer.parseInt(sc.next()));
        return m;
}

Edit: Updated Server Code:

private ExecutorService executor = Executors.newFixedThreadPool(15);
public void listen() throws IOException
    {
        serverSocket = new ServerSocket(port);
        while (!Thread.interrupted()) {
            try
            {
                //Server, Listening........
                clientSocket = serverSocket.accept();
                ServerExecutor serverExecutor = new ServerExecutor(peerID, clientSocket);
                executor.submit(serverExecutor);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        serverSocket.close();
    }

ServerExecutor class:

 public ServerExecutor(int _peerID, Socket _clientSocket)
    {
        this.peerID = _peerID;
        this.clientSocket = _clientSocket;
    }
public void run() 
    {

        try( DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));)
        {

            String data = null;
            while((data = bufferedReader.readLine()) != null)
            {
                Message message = Message.deserializeMessage(data);
                synchronized (PeerNode.requestHistory)
                {
                    if(PeerNode.requestHistory.keySet().contains(message)) 
                    {
                        continue;
                    }
                }
                if(message.getType() == 0 && message.getHopCount() < 1) {
                    continue;
                }
                switch(message.getType()) {
                    case 0:
                        synchronized (PeerNode.sharedRequestBuffer){ 
                              PeerNode.sharedRequestBuffer.offer(message);
                            }
                        break;
                    case 1:
                        synchronized (PeerNode.sharedReplyBuffer) {
                             PeerNode.sharedReplyBuffer.offer(message);
                        }

                        break;
                    case 2:
                        synchronized (PeerNode.numberOfItems) {
                            if(PeerNode.numberOfItems > 0) {
                                PeerNode.numberOfItems -= 1;
                            }
                            outputStream.writeBytes("0" + "\n");
                        }
                        break;
                }
                synchronized (PeerNode.requestHistory) {
                    PeerNode.requestHistory.put(message, 0);
                }
            }
            clientSocket.close();

         }
         catch(Exception ex)
         {
               ex.printStackTrace();
         }
    }

Updated deserialize():

public static Message deserializeMessage(String s)
    {
        Message m = new Message();
        Scanner sc = new Scanner(s);
        sc.useDelimiter("#");
        m.setProductName(sc.next());
        m.setProductId(sc.nextInt());
        List<Integer> tempList = new ArrayList();
        Scanner sct = new Scanner(sc.next());
        sct.useDelimiter(",");
        while(sct.hasNext())
        {
            tempList.add(sct.nextInt());
        }
        m.setMessagePath(tempList);
        m.setHopCount(sc.nextInt());
        m.setType(sc.nextInt());
        m.setRequestId(sc.nextInt());
        m.setSourcePeerId(sc.nextInt());
        m.setDestinationSellerId(sc.nextInt());
        m.setDestinationSellerLocation(sc.nextInt());
        return m;
}

Are you using different thread for each new client connection and also this kinda code will never occupy such a high % of CPU load. Is there some other functionality that's running in the background as well? Edit: Maybe you can try something like this?

while (true)  
{ 
    Socket s = null; 
    ServerSocket serverSocket = new ServerSocket(5555);
    try 
    { 
            s = ss.accept(); //ss is the server socket object
            DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
            BufferedReader int = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            //create a new Thread for the client
            Thread t = new TaskHandler(s, in, out); //run method of Task Handler can have the code you want to execute for each connected client
            t.start(); 
    } 
    catch (Exception e){ 
            s.close(); 
            e.printStackTrace(); 
    } 
} 

Does this help?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM