Non-blocking I/O channels use fewer threads (native or green) than tasks. Some programming languages ARE designed to handle this: they use async/await.
You could argue that Go does this more elegantly with goroutines, but this further highlights the point that threads should not be a silver bullet to development models.
You could argue that Go does this more elegantly with goroutines, but this further highlights the point that threads should not be a silver bullet to development models.