# README
What the Code Does
Imagine you have a bunch of kids who all want to add stickers to the same sticker book. If they all try to do it at the same time, they might accidentally put stickers on the same page or mess up the order. This code is like having a special rule: only one kid can use the sticker book at a time.
-
The Shared Sticker Book (
SharedData
)counter
: This is like the number of stickers in the book.mu
: This is a special lock (a "mutex"). Only one kid can hold the lock at a time, making sure no one else can mess with the book while they're adding a sticker.
-
Adding a Sticker (
increment
)- A kid grabs the lock (
sd.mu.Lock()
). - They add their sticker to the book (increase
sd.counter
). - They put the lock back (
sd.mu.Unlock()
). Thedefer
keyword makes sure this always happens, even if something goes wrong.
- A kid grabs the lock (
-
The Sticker-Adding Task (
doWorkWithMutex
)- Each kid (goroutine) gets a number (
id
). - They say when they start adding their sticker.
- They pretend to take some time to choose the right sticker (
time.Sleep
). - They use the special
increment
method to add their sticker to the book safely. - They say when they're done.
- Each kid (goroutine) gets a number (
-
The Main Program (
main
)- We have 15 kids (
numWorkers
). - We create a brand-new sticker book (
sharedData
). - We tell each kid to start adding their sticker, but they run off to do it concurrently (at roughly the same time) using the
go
keyword. - The
wg.Wait()
line makes the main program wait patiently until all the kids have finished adding their stickers. - Finally, we count the stickers in the book and show the total.
- We have 15 kids (
Thought Process: How to Write Concurrent Code Safely
-
Identify Shared Resources: What things in your code could multiple parts (goroutines) try to access at the same time? In this case, it's the
counter
in thesharedData
. -
Protect with Mutexes: Use a mutex (like
mu
inSharedData
) to create a "one at a time" rule for accessing the shared resource. -
Encapsulate Logic: Create a function (like
increment
) that handles the locking and unlocking for you. This makes the rest of your code easier to read and less prone to mistakes. -
Use a WaitGroup: If your main program needs to wait for all the concurrent tasks to finish, use a
WaitGroup
to keep track of them.
Why This Matters
This code demonstrates how to safely share data between different parts of a concurrent Go program. Without the mutex, the counter
could easily get messed up if multiple goroutines tried to change it simultaneously.
This concept is essential for building reliable and efficient concurrent programs, where multiple tasks are working together but need to access shared resources.