Quote
“Don’t communicate by sharing memory, share memory by communicating.” - Rob Pike
A goroutine is a lightweight thread of execution that is managed by the Go runtime and essentially let us write asynchronous code in a synchronous manner.
- They are not actual OS threads.
- The main function itself runs as a goroutine
A single thread may run thousands of goroutines in them by using the Go runtime scheduler which uses cooperative scheduling. This implies that if the current goroutine is blocked or has been completed, the scheduler will move the other goroutines to another OS thread. Hence, we achieve efficiency in scheduling where no routine is blocked forever.
go fn(x,y,z)Fork - Join Model
The fork-join model essentially implies that a child process splits from its parent process to run concurrently with the parent process. After completing its execution, the child process merges back into the parent process. The point where it joins back is called the join point.

Examples
package main
import "fmt"
func speak(arg string) {
fmt.Println(arg)
}
func main() {
go speak("Hello World")
}func main() {
...
time.Sleep(1 * time.Second)
}Well, the most tricky part about using goroutines is knowing when they will stop. It is important to know that goroutines run in the same address space, so access to shared memory must be synchronized.