Zhro
Zhro

Reputation: 2614

What options are available to me when considering the use of blocking sockets?

While leveraging Java's blocking sockets where I intend to both read and write independently, I see that my two options are either to dedicate a separate thread for each operation or to poll on a timeout using setSoTimeout().

Making a choice between the two implementations appears to be a trade-off of memory (threads) versus CPU time (polling).

I see scaling issues that may occur with regards to scheduler and context switching of many threads which may outweigh the CPU time spent polling as well as latency which may occur between reading and writing from a single thread depending on the size of packets received. Alternatively, a small pool of threads could be used for scale in combination with the polling of several sockets if tuned appropriately.

With the exception of Java's NIO as an alternative, which is outside the scope of this question, am I correctly understanding the options available to me for working with blocking sockets?

Upvotes: 0

Views: 48

Answers (2)

Stephen C
Stephen C

Reputation: 719279

First of all, I think you have excluded the only option that will scale; i.e. using NIO.

Neither per-socket threads or polling will scale.

  • In the thread case, you will need two threads per socket. (A thread pool doesn't work.) That consumes space for the thread stacks and Thread objects, kernel resources for native thread descriptors. Then there are secondary effects such as context switching, extra GC tracing, and so on.

  • In the polling case, you need to make regular syscalls for each socket. Whether you do this with one thread or a small pool of threads, the number of syscalls is the same. If you poll more frequently, the syscall rate increases. If you poll less frequently, your system becomes less responsive.

AFAIK, there are no other options, given the restrictions that you have set.


Now if you are trying to figure out which of threads and polling is better, the answer will be, "it depends". There are lots of variables:

  • The amount of spare physical memory and spare CPU cycles.
  • The number of sockets.
  • The relative activity of the sockets.
  • Requirements for responsiveness.
  • What else is going on in the JVM (e.g. to trigger GCs)
  • What else is going on outside of the JVM.
  • Operating system performance characteristics.

These all add up to a complicated scenario which would probably be too difficult to analyze mathematically, too difficult to simulate (accurately) and difficult to measure empirically.

Upvotes: 1

meriton
meriton

Reputation: 70574

Not quite.

For one, reading with a timeout is no more expensive than reading without one. In either case, the thread goes to sleep after telling the OS to wake it if there is data for it. If you have a timeout, it additionally tells the OS to wake it after the specified delay. No cpu cycles are wasted waiting.

For another, context switching overhead in on the order of a couple thousand cpu cycles, so about a few micro seconds. Delay in network communication is > 1ms. Until this overhead brings a server to its knees, you can probably serve thousands of concurrent connections.

Upvotes: 1

Related Questions