1. Concurrency

If the computer we're running our code on has multiple cores, we can even execute multiple tasks at exactly the same time. If we're running on a single core, a single core executes code at almost the same time by switching between tasks very quickly. Either way, the code we write looks the same in Go and takes advantage of whatever resources are available.

How Does Concurrency Work in Go?

Go was designed to be concurrent, which is a trait fairly unique to Go. It excels at performing many tasks simultaneously safely using a simple syntax.

There isn't a popular programming language in existence where spawning concurrent execution is quite as elegant, at least in my opinion.

Concurrency is as simple as using the go keyword when calling a function:

go doSomething()

In the example above, doSomething() will be executed concurrently with the rest of the code in the function. The go keyword is used to spawn a new goroutinearrow-up-right.

What is Concurrency?

Concurrency = doing multiple things at the same time (or appearing to)

Multiple Cores

Core 1: Task A running
Core 2: Task B running
Core 3: Task C running
(All truly simultaneous)

Single Core

Core 1: Task A β†’ Task B β†’ Task C β†’ Task A β†’ Task B...
(Switching so fast it feels simultaneous)

The go Keyword

Spawns a goroutine (concurrent execution):

This runs doSomething() concurrently while the rest of your code continues.

Basic Example

1

Without Concurrency (Sequential)

2

With Concurrency (Parallel)

Real Example

Output:

With Concurrency

Output (interleaved):

Numbers and letters print at the same time!

Goroutines

A goroutine is a lightweight thread managed by Go:

Key facts:

  • Very lightweight (can have thousands)

  • Managed by Go runtime, not OS

  • Start with go keyword

circle-exclamation

Example showing the issue:

A quick (but crude) way to wait:

(We'll learn better ways to wait later, e.g., sync.WaitGroup, channels.)

Practical Example

Why Go is Good at This

Other languages:

Go:

Simple and elegant!

Concurrency vs Parallelism

Concurrency: Managing multiple tasks (may or may not run at exact same time) Parallelism: Actually running multiple tasks at exact same time

Go handles both automatically based on available CPU cores.

Key Takeaways

  1. go keyword spawns a goroutine

  2. Goroutines are lightweight concurrent tasks

  3. Very simple syntax - just add go before function call

  4. Main doesn't wait - need to handle synchronization

  5. Works on any hardware - Go optimizes automatically

Quick Reference

Rule: Use go when you want something to happen concurrently while your code continues running.

Assignment

At Textio we send a lot of network requests. Each email we send must go out over the internet. To serve our millions of customers, we need a single Go program to be capable of sending thousands of emails at once.

Edit the sendEmail() function to execute its anonymous function concurrently so that the "received" message prints after the "sent" message.

Suggested edit (launch the anonymous function as a goroutine after printing "sent"):

This ensures the anonymous function runs concurrently and its "received" message happens after the "sent" message for the same email.