• Post Reply Bookmark Topic Watch Topic
  • New Topic

CPU Usage and NIO  RSS feed

 
Jason Cox
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the "traditional" java server model, a server would have multiple "lazy" threads waiting to process requests. While idle, these threads would most likely be in a wait state and not really using much CPU time. These threads might be in a wait or blocking IO.
The new model using NIO seems to be that the thread listening on the server socket doesn't block but loops continuously checking the Selector(s) and processing other requests previously aquired. In most examples of NIO they design a simple "echo" type server that does just this. However, when the server is in an idle state and just waiting for connections, the thread just loops continuously. This seems to use quite a bit of CPU time.
What techniques would you recommend to keep the app from abusing the CPU while in an idle state?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It loops "continuously," but ServerSocketChannel.accept() blocks by default. Thus a loop like the one in the TimeServer example spends most of its time just waiting for accept() to return:

just like the traditional model you describe.
 
Jason Cox
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
It loops "continuously," but ServerSocketChannel.accept() blocks by default.

True, by default it does block. However, most examples I have seen set the ServerSocketChannel.configureBlocking() to false. This allows the same thread to process socket reads and still accept new connections without blocking on either. Perphaps I'm wrong but it seems that one of the main arguments for NIO is that you can perform asynchronous IO without using multiple threads and thereby avoid the overhead of the added memory and context-switching required by threads. If you blocked on accept() you would only be able to handle a single connection at a time with one thread.
 
Jason Cox
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Perhaps I can answer my own question now after reading a bit more information. If anyone can confirm this or dispute it, please do so. I'm just trying to figure this out.
It appears that the select() method on the selector will block. By registering both the accept and read ops, you can safely block on the select. This will allow you monitor both states and still remain in a wait state during idle times.
Would that be a preferred method?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's right. The select() method blocks until something happens, or until it times out, even if the channels it's selecting from are nonblocking. For efficiency, using a Selector this way is probably the preferred approach.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!