I am wondering if a typical while(true)
ServerSocket listen loop takes an entire core to wait and accept a client connection (Even when implementing runnable and using Thread .start()
)
I am implementing a type of distributed computing cluster and each computer needs every core it has for computation. A Master node needs to communicate with these computers (invoking static methods that modify the algorithm's functioning).
The reason I need to use sockets is due to the cross platform / cross language capabilities. In some cases, PHP will be invoking these java static methods.
I used a java profiler (YourKit) and I can see my running ServerSocket listen thread and it never sleeps and it's always running. Is there a better approach to do what I want? Or, will the performance hit be negligible?
Please, feel free to offer any suggestion if you can think of a better way (I've tried RMI, but it isn't supported cross-language.
Thanks everyone
You might want to take a look at the Java 1.4 nio libraries and in particular ServerSocketChannel. I use this very successfully to implement an efficient server, the key bits of code are:
And the listener is just a loop that runs:
Let the core sleep a little. In your Runnable method, add something like
in every loop.
That should significantly reduce CPU usage
Edit: bad idea, see comments, sorry, my fault
And: don't use while(true). it's awful design, as the semantics suggest that eventually true will not be true anymore. Usually you will want to query some volatile or atomic variable from the main thread
That way the main thread has a way to stop the listener thread.
If you mean something like this:
then, no, the call to
accept()
does not "take an entire core." It's a blocking call that will allow the CPU to be scheduled for another thread until a client actually connects. Once the call toaccept()
returns, the current thread will be scheduled to run and will consume CPU until it blocks onaccept()
in the next iteration of the loop.To avoid the listen backlog of other clients growing too large, another thread usually handles interaction with the newly-accepted
Socket
, leaving one thread to focus on accepting new clients. The socket handling thread might handle many sockets, using NIO, or it might be dedicated to a single socket, which is much simpler to code but won't scale well past many hundreds of simultaneous connections.Basically, the profiler is misleading you.
I assume your code looks like this:
This will not consume significant CPU ... unless you have done something pathological, like calling
ServerSocket.setSoTimeout(int)
with a small timeout.