Interview_concurrency, multi thread, synchronized, volatile, visibility, atomic
✅ concurrency과 parralelism의 차이
- concurrency: single core, multi thread, process takes turn
- looks like several jobs are done at the same time, but actually one job is done at once
- parrellelism: multicore, several CPU
✅ Thread-Safe하다는 것이 무슨 의미인가요?
- shared data is accessed and modified safely by multiple threads without causing inconsistent or unexpected behavior.
- data consistency, integrity is maintained
Data consistency 🆚 integrity
- Data consistency: data state is correct(I moved $100 from A to B, but the sum is consistent)
- Data integrity: data accuracy and validity(birthday
2033-13-99
violates data integrity)
✅ ACID of reliable database transactions
- A: Atomicity
- C: Consistency
- I: Isolation, transactions are independent
- D: Durability, once transaction is commited, changes are permanent, write DB to non-volatile storage(even if I restart database)
✅ Thread-Safe 구현방법
- 1️⃣ use
synchronized
keyword
1
2
3
4
5
6
7
8
9
10
11
public class Counter {
private int count = 0;
public synchronized void increment() { //synchronized
count++;
}
public synchronized int getCount() {
return count;
}
}
- 2️⃣ use
java.util.concurrent
Package reentrantLock
: more granular lockAtomicInteger, AtomicBoolean
: lock-free thread safe variableConcurrentHashMap
: thread safe collection- concurrent: happening at the same time
1
2
3
4
5
6
7
8
9
10
11
public class Counter {
private AtomicInteger count = new AtomicInteger();
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
- 3️⃣ Thread safe collections
ArrayList
➡️CopyOnWriteArrayList
HashMap
➡️ConcurrentHashMap
Queue
➡️ConcurrentLinkedQueue
- 4️⃣ use Immutable
- immutable is thread safe as it cannot be changed after construction
1
2
3
4
5
6
7
8
9
10
11
12
public final class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
//only constructor, getter
//no setter
- 5️⃣ use Volatile
- volatile: varible that can be accessed by multiple thread, ensuring visibility of changes
- any write of this variable is immediately visible
- read of this varible is done directly by main memory, not from cache
- always read the latest, updated value
- ⭐️ force memory sync
- 👍🏻 lighter(no locking)
- 👎🏻 however, atomicity is not guaranteed
- use volatile for simple flags
- cannot use volatile for
count++
(no atomacity) ➡️ usesynchronization
orAtomicInteger
1
2
3
4
5
6
7
8
9
10
11
12
13
public class FlagExample {
private volatile boolean running = true;
public void run() {
while (running) {
// do something
}
}
public void stop() {
running = false;
}
}
- Synchronization 🆚 Volatile
- Synchronization: visibility, atomacity, but slower
- Volatile: visibility, lighter and fast, but no atomacity
✅ Methods to ensure Thread-Safety
- 1️⃣ mutual exclusion(Locks):
semaphore(semaphore variable)
,mutex(0, 1)
- 2️⃣ atomic operations: operation happens or not
- 3️⃣ thread local storage: thread has own copy of data, do not share
- 4️⃣ reentrancy: make program with no static, no global variables, no shared memory ➡️ only local variables(each thread saves variable on stack, has own copy)
✅ What problems can occur in parrallel programming? Mutli CPU?
- visibility problem
- atomacity problem
✅ Visibility and Atomicity Problems in Multithreading
- 💣 Visibility problem: one thread updates shared variable, but other threads don’t see
- threads dont see the latest updated value
- because they are using outdated copy in cache
- 💊 use
volatile
: force memory sync, read and write directly to RAM, not cache 💊 use
synchronized
: makes code block execute as one unit, solves both visibility problem and atomacity problem- 💣 Atomicity Problem: thread is interrupted during operation, operation is partially updated
- 💊 use
synchronized
: keywordsynchronized
ensures only one thread at a time executes the code - 💊 use
AtomicInteger
atconcurrent
package
⚠️ Why does concurrency problems occur?
- each CPU has own cache, does not always read from RAM
- and parrallelism
✅ 자바의 동시성 이슈를 해결하는 방법을 아는만큼 설명해 주세요.
- 1️⃣ use
Synchronized
: only one thread can access code block - 2️⃣ use
volatile
: save varible in main memory, other threads can always have updated latest value - 3️⃣ use
Atomic class
,concurrent package
: CAS(Compare and Swap) algorithm, guarantee synchronization
✅ volatile 키워드가 무엇인가요?
- force memory sync with main memory
- save variable on main memory, not cache
- guarantee threads read from main memory, reading latest updated value
- 👍🏻 solve visibility problem
- 👎🏻 however, does not solve the atomacity problem
- used for flag, simple variables
- cannot use for
count++
, more complex synchronization
✅ synchronized 키워드가 무엇인가요?
- ensure atomacity of code block with keyword
synchronized
- ensure synchronization in multi threading environment
- 👍🏻 solve visibility problem, atomacity problem
- mutual lock: only one thread can enter
synchronized
block, method - ensure visibility
- Reentrancy: thread can enter if it has lock
✅ synchronized의 문제점은 무엇이 있나요?
- 1️⃣ Performance Overhead: slow, need to aquire, release lock
- context swithcing, blocking
- 2️⃣ deadlock: two threads ask for same resource without giving up their resource, end up no thread getting resource
- 3️⃣ starvation, inefficient use of CPU: only one thread can access, rest have to wait
- 4️⃣ less flexible
✅ How is synchronized implemented in Java?
- use
object monitor lock(monitor)
which is built into JVM - every object has monitor: speical structure used to control thread access
- JVM manages monitor
monitor allows one thread at a time to run
synchronized
codeMonitor lock
: lock mechanism that control thread access insynchronized
- if thread wants to enter
synchronized
code, must aquire monitor lock first - if lock is available, the thread will enter the
synchronized
block - if another thread has already entered, has to wait
✅ What is Reentrancy?
- thread can re-enter a block of code it already has lock, without getting blocked or deadblocked
- this behavior is built into
synchronized
keyword - Java has an
internal counter
to track reentrant locks
✅ atomic하다는 것이 무슨 의미인가요?
- operation will happen, or not happen at all
- if there is a interruption in operation, rollback
✅ atomic 타입이 무엇인가요
- atomic type is to ensure atomacity in multi thread environment even without lock
AtomicInteger
: ensure atomicity of variableAtomicLong
,AtomicBoolean
,AtomicReference
,AtomicStampedReference
✅ CAS 알고리즘에 대해 설명해 주세요
- CAS: Compare and Swap
- atomic operation in multi thread programming to safely update shared variables without using lock
- used in atomic types like
AtomicInteger
1
Only change the value if it has NOT changed since I last checked it
- compare: did it change?
- swap: if it did not change, change to new value
if it changed, someone else updated it, so don’t change, try later
- 👎🏻 ABA problem: if value was changed from A ➡️ B ➡️ A, thread will think value did not change
- 👎🏻 if repeated failiure, CPU usage: if fail to swap, keep try again later
✅ SynchronizedList와 CopyOnArrayList의 차이를 설명해 주세요
SynchronizedList
: only one thread can access list- 👍🏻 multi thread safe, read and write synchronized
👎🏻 not very performant
CopyOnArrayList
: when there is write, copy and create new array- 👍🏻 no locking
- 👎🏻 write is expensive: need to copy whole list, need to increase memory usage
✅ ConcurrentHashMap의 동작 과정을 SynchronizedMap과 비교하여 설명해 주세요.
SynchronizedMap
: only one thread can access map- use lock
👎🏻 not very performant, slow
ConcurrentHashMap
: divide map into segments- read: non-blocking
- writing: block only small segment of map
- 👍🏻 multi thread safe, fast
✅ Vector, Hashtable, Collections.SynchronizedXXX의 문제점은 무엇인가요?
- 👎🏻 global locking: only one thread can write/read
- 👎🏻 same lock for read and write: if one thread is reading, blocking thread is also blocked
- 👎🏻 scalability issue: cannot scale to multi-core systems, create bottleneck
- 🚫 not recommended to use
Vector, Hashtable, Collections.SynchronizedXXX
- 🍀 instead, use
ConcurrentHashMap
,CopyOnWriteArrayList
.concurrent package
✅ 가시성 문제에 대해 조금 더 자세히 설명해 주세요. 여러 스레드가 모두 한 CPU의 캐시 메모리를 읽으면 가시성 문제가 발생하지 않을 것 같은데, 어떻게 생각하시나요?
- 🔶 multi core processor: each CPU has own cache
🔶 cache coherence delay: cache copy is not instantaneous, can have delay
- 💊
volatile
- 💊
synchronized
- 💊 use
final
✅
✅
This post is licensed under CC BY 4.0 by the author.