Does each thread get a separate V8 interpreter? I was pretty sure that V8 has a GIL (at least at the Isolate level), just like Python and (Matz) Ruby, and so how do they handle lock contention between multiple threads?
No, because the I/O threads never enter JS land (V8); they just dump their data for the main V8 thread to pick up.
And yes you are correct that V8 effectively has a GIL for its Javascript execution (though V8 does actually run other threads in the background for profiling).
But for web workers there are two threads executing JavaScript in parallel no? However they cannot share state. They can only communicate via messages. It's basically the actor model and it does demonstrate how effective and safe it can be (although Erlang already demonstrated that in spades). No pure FP needed! (although in theory I suppose you could deadlock with two workers waiting on each other for a message)
And yes you are correct that V8 effectively has a GIL for its Javascript execution (though V8 does actually run other threads in the background for profiling).