Week 8 Review — Concurrency
Goal
This review checks whether I can keep a singleton stateless, pick lock vs volatile vs atomic, bound a pool, and explain why @Async does not see the caller’s transaction.
Week 8 topics:
- Threads vs process, shared beans
synchronized,ReentrantLock,volatile, atomics- Happens-before and safe publication
- Executors and
CompletableFuture @Async,@Transactional,ThreadLocal
1. Week 8 big picture
HTTP thread-1 ──▶ OrderService @1 ──▶ @Transactional ThreadLocal session
HTTP thread-2 ──▶ OrderService @1 ──▶ its own ThreadLocal
│ this.send() skips proxy
▼
MailService proxy @Async ──▶ orders-3 pool thread
new transaction or none
no caller session
MDC/security need a decorator
2. Core memory sentences
One JVM, many threads, shared singleton beans.
Request state stays on the stack. The singleton holds collaborators.
Locks exclude and publish.
volatileonly publishes.++needs a lock or an atomic.
If there is no happens-before, there is no visibility guarantee.
Bound the pool and the queue; unbounded thread creation is a leak.
Pass your executor to
thenApplyAsync. The common pool is not for JDBC.
@Asyncis a proxy that submits the method.thisis not the proxy.
The persistence context is bound to the thread that opened the transaction.
ThreadLocalon a pool thread leaks unless Iremove.
3. Speak these without notes
- Why a mutable field on
@Serviceis a bug. volatile++vsAtomicInteger.- Double-checked locking and
volatile. - Unbounded queue vs
maxPoolSize. @Asyncinside@Transactional: which session, which thread, after-commit?
4. Tiny code proofs
Proof A — race
Two threads increment a plain int 100_000 times each. Print the total. Repeat with AtomicInteger.
Proof B — spent vs submitted
Log Thread.currentThread() in an @Async method and in its caller. Confirm different names. Then call this.asyncMethod() and confirm the same name.
Proof C — ThreadLocal leak
Set a ThreadLocal on a fixed pool of size 1, omit remove, submit a second task that prints the value. Then fix with finally remove.
5. Common mix-ups from this week
| Mix-up | Clear line |
|---|---|
| Tomcat is another process | Embedded Boot: one JVM |
volatile++ is atomic | Visibility only |
newCachedThreadPool for HTTP | Unbounded threads |
@Async joins the transaction | Different thread, different ThreadLocal |
this.@Async works | Proxy skipped |
| Sleep makes writes visible | Not a happens-before |
6. Interview drill
Open Concurrency and JVM:
- Process vs thread; what Boot runs
synchronizedvsReentrantLockvsvolatile- Happens-before / stale data
- Thread pools vs
new Thread() CompletableFutureand@AsyncThreadLocaluses and leaks
GC, virtual threads, and stack vs heap recap wait for Week 9 and Week 1.
7. Ready for Week 9?
I am ready if I can refuse a mutable field on a service, bound an executor, and explain ThreadLocal for transactions.
Week 9 is modern Java for Boot 3/4: records recap, sealed types, pattern matching, virtual threads.