Q — Questions (Preguntas)
Convierte los encabezados en preguntas de estudio:
¿Qué es un mecanismo de bloqueo (lock) y para qué se usa en concurrencia?
Un "lock" es un mecanismo de sincronización de hilos que sirve para proteger el acceso y modificación de un dato. Se usa en concurrencia para que no haya carreras de datos.
¿Cómo protege NSLock el acceso a datos mutables compartidos en la clase BankAccount?
En BankAccount hay una propiedad, balance que se debe proteger con un NSLock: Cada vez que se accede al método se bloquea (.lock()) y justo antes de salir de cada método se libera (.unlock()).
¿Por qué el ejemplo de BankAccount es útil para entender los actores más adelante?
En el contexto de concurrencia de Swift, el actor permite invocar sus métodos con await con lo que consigue serializar los accesos a los datos. Si se va a escribir código nuevo, lo ideal es usar un actor. Sin embargo, en código pre-existente hay que evaluar si basta con usar @unchecked Sendable.
El ejemplo inicial de BankAccount ilustra el acceso a balance de forma serializada con ayuda del NSLock. Usar el lock es una convención. Por otro lado, la implementación con actor también serializa el acceso a los datos (en este caso, balance) con la diferencia de que aquí no hay ninguna convención sino que el lenguaje garantiza este comportamiento.
¿En qué situaciones conviene usar @unchecked Sendable en lugar de refactorizar a un actor?
Si el código es bastante estable, la sincronización del acceso a datos es segura, y si la clase en cuestión tiene muchos clientes y su refactorización puede ser compleja, se puede usar @unchecked Sendable.
¿Qué implica técnicamente migrar una clase con locks a un actor en Swift?
Acceder a todos los métodos requiere usar await, lo que implica que el consumo es asíncrono.
¿Cuáles son las desventajas de migrar de inmediato a un actor en una base de código existente?
Se tendría que modificar a todos los clientes para invocar los métodos del actor con await.
¿Cuándo se recomienda usar Mutex en lugar de NSLock o actores?
Si se quiere sincronizar los hilos y también tener acceso a la clase en cuestión de forma síncrona, entonces se usa Mutex.
R — Recite (Recitar)
Sin mirar el texto, responde con tus propias palabras:
¿Cómo funciona el flujo de bloqueo/desbloqueo en BankAccount?
final class BankAccount: @unchecked Sendable {
private var balance: Int = 0
private let lock = NSLock()
func deposit(amount: Int) {
lock.lock()
balance += amount
lock.unlock()
}
func withdraw(amount: Int) {
lock.lock()
if balance >= amount {
balance -= amount
}
lock.unlock()
}
func getBalance() -> Int {
lock.lock()
let currentBalance = balance
lock.unlock()
return currentBalance
}
}
actor BankAccount {
private var balance: Int = 0
func deposit(amount: Int) {
balance += amount
}
func withdraw(amount: Int) {
if balance >= amount {
balance -= amount
}
}
func getBalance() -> Int {
return balance
}
}
¿Qué garantiza @unchecked Sendable y qué responsabilidad transfiere al desarrollador?
¿Qué cambia en el código que consume BankAccount cuando se migra a actor?
R — Review (Revisión)
Preguntas de repaso para consolidar:
Top comments (0)