Another very large difference between BEAM and the JVM is that BEAM operates on 'reductions' and when a thread has exhausted it's fair share of reductions another thread is scheduled. So even though the scheduler is not pre-emptive (interrupt based) the effect is very much the same as if it were with less overhead.
But that's an implementation detail of a high-level user-mode thread implemented on top of kernel threads, and something you can implement on the JVM (I know I have) at the language level just like BEAM implements that in C.