Designing Thread-Safe Code
Concurrency: lesson 10 of 10
Don't share, freeze it, or guard it.
Lesson 10 of 10 · 5 min
Designing Thread-Safe Code
Step 1 of 9
step0 — plan
Work down the list in order: don't share it, freeze it, or guard it.
The Idea
Work down the list. Give each thread its own state; make whatever must be shared immutable; guard the small remainder with one lock whose scope is written down. Reach for clever lock-free tricks only after the first three have genuinely failed.
Real-World Example
A museum conservation studio. Each conservator has a private bench for the object in their care, the reference photographs on the wall are read-only prints anyone may consult, and the single vacuum table has a booking sheet by the door.
The Code
import threading
readings = [3, 8, 1, 9, 4, 7] # shared, but never mutated
totals = {}
lock = threading.Lock() # guards: totals, and nothing else
def sum_chunk(name, chunk):
subtotal = sum(chunk) # thread-local work, no lock needed
with lock:
totals[name] = subtotal
parts = {"left": readings[:3], "right": readings[3:]} # private slices
ts = [threading.Thread(target=sum_chunk, args=kv) for kv in parts.items()]
for t in ts: t.start()
for t in ts: t.join()
print(sorted(totals.items()), sum(totals.values()))
Your turn
Put the steps in the right order.
- Guard whatever genuinely remains with one documented lock
- List every piece of state that two threads can reach
- Give each thread its own copy of what it alone writes
- Freeze the shared data that never changes after creation
Mini quiz
1 / 3