From: Thomas Pornin on
According to Arne Vajh�j <arne(a)vajhoej.dk>:
> On high-end HW you can support hundreds of threads.

Apart from the creation cost, having a thread around costs a bit in
RAM (actually address space), and a bit in scheduler efficiency.

The address space cost is for the thread stack. Thread stack size
depends on the operating system and can be changed (with Sun's JVM,
there is a -XX:ThreadStackSize parameter just for that). A typical size
is 1 MB. Most of it will remain untouched and thus not really allocated
(the address space chunk will be reserved, but the pages will not
exist). One thousand threads is 1 GB of address space; this may cause a
bit of trouble on 32-bit architectures, if the Java heap is also quite
big (thread stacks are allocated _outside_ of the Java heap). The
thousand stacks will use only a few dozen megabytes of actual RAM, no
worry here. On a 64-bit architecture, there is no shortage of address
space, and you can create thousands of threads without any problem.

The scheduler is the part of the operating system which decides which
thread should run next. Depending on the operating system, this may be
entirely in the OS kernel (Linux) or partially handled in userland
(Solaris). Either way, what happens which so many threads depends on the
algorithms which are used. Traditional, old-style schedulers are fine
with hundreds of threads but may begin to lose efficiency when reaching
the thousands. However, it is said that Solaris is very good at handling
many threads, and "recent" Linux kernels (I mean, since the 2.6.0
kernel, which is not in fact very recent) have been greatly improved:
they can handle _millions_ of runnable threads, with no worry.

Also, if you go the NIO road, then what this means is that you are
handling your own scheduling, in Java, with the constraint that
information about who may run must fit in the NIO API. It may provide a
gain only if the NIO API happens not to constrain too much, _and_ you
beat the carefully tuned kernel algorithms at their own game. I find
this to be a bit lacking in plausibility. And even if you succeed, you
end up with your own set of kind-of threads, except that Java does not
have coroutines, so things remain irksome.


To sum up:

-- You can go to thousands of threads with Java.

-- The limits are bound to address space allocation, and can be lifted
by using the -XX:ThreadStackSize flag, or, more appropriately, by using
the hardware at its full potential, i.e. using a 64-bit OS.

-- NIO will not help you with scheduling issues, unless you happen to
use a primitive operating system _and_ you are much better at
programming than the OS designers. With a non-primitive OS there will be
no scheduling issue.

-- NIO comes with a price in usability, since you have to fit several
conceptual execution threads on the same stack.


--Thomas Pornin