Fork is commonly confused with spawn.
Spawn is fork + exec (which means start a process
which replaces the current one and inherits some of
its external resources, such as open sockets).
Spawn is available in Java (via System.exec and the like).
Fork is not in Java, because it would be extremely problematic.
Fork requires cloning of the address space.
The kernel support to do this efficiently is not available
in most non-Unix OSes; e.g. U/win and Cygwin have struggled
to emulate fork under Win32.
In a language such as Java, the garbage collector
& JIT compilers would tend to touch Vmem pages such
that the space would not long remain shared after fork.
Cloning has many side effects.
E.g., input or outputs buffers will be processed in all
of the forked children. SysV shared memory will be detached.
Most languages and many libraries simply refuse to
support forking. This includes the (POSIX) threading API ;
The child is not allowed to use threads until it execs
(i.e., becomes a spawn) !
Perl uses fork because its internals are extremely close to C/Unix,
and its multithreading is abysmal.
Unix shell uses fork by design, which is how it snapshots
all local variables and state. That's also why there is no
decent Unix shell for a non-Unix environment.