I've seen a lot of topics comparing the older Java io model to the newer java nio model, the former being synchronous/blocking and the latter being asynchronous/non-blocking. Because nio is non-blocking, it is more suitable than java io when a large number of concurrent connections need to be processed concurrently without allocating a large number of threads which does not scale well due to context switching/memory usage.
The problem I have with this argument is that comparisons of IO to NIO always give examples of IO using a thread per connection. Could a developer using java IO simply allocate a finite number of threads (thread pool) for blocking IO operations (ie file reading or database queries) and queue them? Let's say I'm making an http server from the ground up using java's ServerSocket class. Let's say I get a request from a client that requires me to make a database query which is a blocking operation due to the JDBC spec. Could I not simply queue the database query to a ThreadPool and hand the job a callback to run when the pool finishes handling it? Sure, I'm allocating threads to handle io-bounds requests, but the number of Threads are finite. Since IO operations are typically synchronous (to a degree), it would be pointless to try to allocate a thread per db query, or thread per file read/write.
This way you can get the benefits of Threads and asynchronous programming without the consequence of allocating too many Threads.
The only weakness I can see in this model is if all io-bound operations get stuck (possibly due to programming error) future queued requests will be put on hold until they either get unstuck, or time out. The main logic is still concurrent, but the IO is not.
So, question: Does NIO solve any problems that just can't be solved with the model I've described above (bar the potential weakness I just mentioned)?
Of course you can do this with a pool and a finite number of threads and handle your own I/O, but you'd be basically duplicating what NIO is providing for you, but without being able to take advantage of native API's.
One of the problems your system could not handle very well is having thousands of sockets doing slow I/O as would be needed for handling server push, a BitTorrent client or perhaps a very busy content server.
More traditional request/response systems would work fine with your solution, but then again, they would also work fine with a thread per request as usually the first bottleneck encountered will be CPU or Memory consumption.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With