Skip to main content

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:

  1. Threads vs process, shared beans
  2. synchronized, ReentrantLock, volatile, atomics
  3. Happens-before and safe publication
  4. Executors and CompletableFuture
  5. @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. volatile only 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.

@Async is a proxy that submits the method. this is not the proxy.

The persistence context is bound to the thread that opened the transaction.

ThreadLocal on a pool thread leaks unless I remove.


3. Speak these without notes

  1. Why a mutable field on @Service is a bug.
  2. volatile++ vs AtomicInteger.
  3. Double-checked locking and volatile.
  4. Unbounded queue vs maxPoolSize.
  5. @Async inside @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-upClear line
Tomcat is another processEmbedded Boot: one JVM
volatile++ is atomicVisibility only
newCachedThreadPool for HTTPUnbounded threads
@Async joins the transactionDifferent thread, different ThreadLocal
this.@Async worksProxy skipped
Sleep makes writes visibleNot a happens-before

6. Interview drill

Open Concurrency and JVM:

  • Process vs thread; what Boot runs
  • synchronized vs ReentrantLock vs volatile
  • Happens-before / stale data
  • Thread pools vs new Thread()
  • CompletableFuture and @Async
  • ThreadLocal uses 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.

Next: Week 9 Day 1 — Java Versions for Spring Boot