Although threads seem to be a small step from sequential computation, in fact, they represent a huge step.
A common solution to this problem is providing an I/O API that implements a synchronous interface by using non-blocking I/O internally, and scheduling another user thread or fiber while the I/O operation is in progress.