How does Go handles concurrency?

Go provides a powerful concurrency model based on Goroutines and channels, which allows for efficient and safe execution of concurrent tasks.

Goroutines are lightweight, concurrent functions that can be executed in parallel with other code. They are similar to threads in other programming languages, but they are much cheaper to create and use. Goroutines are managed by the Go runtime, which schedules them onto available processors as needed.

Channels are used to communicate between Goroutines. They provide a way for Goroutines to send and receive messages to each other, and can be used to coordinate concurrent tasks. Channels in Go are typed, meaning that they can only send and receive values of a specific type.

Here's an example of how to use Goroutines and channels to implement a simple concurrent program:

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("worker", id, "processing job", j)
        results <- j * 2

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)

    for j := 1; j <= 5; j++ {
        jobs <- j

    for a := 1; a <= 5; a++ {

In this example, we define a **worker()** function that takes an ID, a channel of jobs to process, and a channel of results to send the processed jobs to. The **worker()** function loops over the jobs in the **jobs** channel, processes them (in this case, by sleeping for a second and then doubling the job value), and sends the results back to the **results** channel.

In the **main()** function, we create channels for the jobs and results, and start three Goroutines to process the jobs using the **worker()** function. We then send five jobs to the **jobs** channel and close it to indicate that there are no more jobs to process. Finally, we wait for all five results to be received from the **results** channel.

This example demonstrates the power of Go's concurrency model: by using Goroutines and channels, we can easily process multiple jobs in parallel, without worrying about thread synchronization or other low-level details.

Related Questions You Might Be Interested