marco
marco

Reputation: 297

BufferedInputStream available() eating CPU

I'm reading messages from a socket (trough a TCP protocol), but I note that the CPU spend a lot of time to call the method available() of my BufferedInputStream. This is my code:

    @Override
public void run()
{

    Socket socket;
    Scanner scanner;
    BufferedInputStream buffer = null;

    try
    {
        socket = new Socket(SERVER_HOST, SERVER_PORT);

        System.out.println("Connection Completed");

        InputStream inputStream = socket.getInputStream();
        buffer = new BufferedInputStream(inputStream);

        StringBuilder readCharacter;

        while (true)
        {

            readCharacter = new StringBuilder();
            try
            {

                while (buffer.available() > 0)
                {
                    readCharacter.append((char) buffer.read());
                }

            }
            catch (IOException e)
            {
                e.printStackTrace();
                buffer.close();
            }

            String array[] = separe(new String(readCharacter));
         ... //parsing the message

I've also tried to use int read=buffer.read() and check if (read!=-1) instead of using the available function, but in this case I'm not able to recognize the end of the message...in my StringBuilder 'readCharacter' I have more than one message, one after the other..and it cause the fail of my parsing process...

Instead using the available() check, into the readCharacter I have only one message at a time..and the parsing works...

Can you help me to understand why, and how avoid the eating of CPU?

Upvotes: 2

Views: 1890

Answers (2)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340743

This loop:

while (buffer.available() > 0)
  {
  readCharacter.append((char) buffer.read());
  }

can be replaced with simple:

readCharacter.append((char) buffer.read());

Instead of calling non-blocking available() over and over again (which consumes a lot of CPU) just call read() which will block not consuming CPU until something is available. Looks like this is what you want to achieve with less code and complexity.

Upvotes: 3

AlexR
AlexR

Reputation: 115338

The available() itself does not eat CPU. What does it is your loop:

while (buffer.available() > 0) {
    readCharacter.append((char) buffer.read());
}

While bytes are unavailable you are actually calling available() multiple times (probably thousands of times). Since read() method of streams is blocking you do not have to call available() at all. The following code does the same but does not eat CPU.

String line = null;
while ((line = buffer.read()) != null) {
    readCharacter.append(line);
}

Upvotes: 1

Related Questions