Its solving the function colouring issue. Your code can run against old-school OS-threads with blocking I/O, or it can run against virtual threads with non-blocking I/O that look and behave almost exactly the same, but are multiplexed onto fewer underlying OS threads, without needing to introduce language constructs such as async/await or changing anything in your program code except maybe the executor implementation.
Golang is opinionated towards its single coroutine model, there is no way to switch. Its a good model and it works well, but there are cases where it leaks, such as low-performance C interop.
Green threads usually refer to single-threaded runtimes such as Node.