Section 6/101 menit
6. Kapan Harus Digunakan
6. Kapan Harus Digunakan
Gunakan Mutex<Value> ketika:
1. State yang perlu banyak field diupdate atomik bersama
swift
// Beberapa field harus konsisten satu sama lain
struct NetworkState {
var isConnected: Bool
var lastError: Error?
var reconnectAttempts: Int
}
let networkState = Mutex(NetworkState(isConnected: false, lastError: nil, reconnectAttempts: 0))
// Update semua field dalam satu lock — konsisten
networkState.withLock { state in
state.isConnected = false
state.lastError = connectionError
state.reconnectAttempts += 1
}
2. Synchronous code yang tidak bisa pakai actor (tidak bisa await)
swift
// Misalnya delegate methods, init, atau synchronous path
class URLSessionManager: NSObject, URLSessionDelegate {
private let activeRequests = Mutex([UUID: URLSessionTask]())
// URLSessionDelegate method adalah synchronous — tidak bisa await actor
func urlSession(_ session: URLSession, task: URLSessionTask, didComplete: Error?) {
activeRequests.withLock { requests in
requests = requests.filter { $0.value !== task }
}
}
}
3. Non-blocking lock attempt diperlukan
swift
let resource = Mutex(Resource())
// Coba tanpa blocking
if let result = resource.withLockIfAvailable({ $0.process() }) {
use(result)
} else {
// Resource sedang dipakai — coba lagi nanti atau skip
scheduleRetry()
}
Gunakan Atomic<Value> ketika:
1. Single primitive yang diakses concurrent
swift
let activeConnectionCount = Atomic(0)
// Di setiap connection open:
activeConnectionCount.add(1, ordering: .relaxed)
// Di setiap connection close:
activeConnectionCount.subtract(1, ordering: .relaxed)
// Baca total:
let total = activeConnectionCount.load(ordering: .relaxed)
2. Lock-free flag / once
swift
let isInitialized = Atomic(false)
func initialize() {
// Hanya inisialisasi sekali, bahkan dari concurrent threads
let (exchanged, _) = isInitialized.compareExchange(
expected: false,
desired: true,
ordering: .acquiringAndReleasing
)
guard exchanged else { return } // sudah diinisialisasi thread lain
// Lakukan inisialisasi...
setupDatabase()
loadConfiguration()
}
3. Performance-critical counter
swift
// Profiling atau metrics di hot path — Atomic jauh lebih cepat dari Mutex untuk ini
struct Metrics {
let requestCount = Atomic(0)
let errorCount = Atomic(0)
let totalLatencyMicros = Atomic(Int64(0))
func recordRequest(latencyMicros: Int64, isError: Bool) {
requestCount.add(1, ordering: .relaxed)
if isError { errorCount.add(1, ordering: .relaxed) }
totalLatencyMicros.add(latencyMicros, ordering: .relaxed)
}
var averageLatency: Double {
let count = Double(requestCount.load(ordering: .relaxed))
let total = Double(totalLatencyMicros.load(ordering: .relaxed))
return count > 0 ? total / count : 0
}
}