There are several places in the SDK that require synchronization. In other words, the SDK needs to ensure that multiple users can't simultaneously read and write while causing data races.
To aid with that task there are several abstractions available:
### `Lock`
This type is a building block to guarantee such synchronization. Its only method `perform` can be used to do that:
If what needs to be synchronized is a piece of data, this can be more easily accomplished using `Atomic`. It serves the same purpose as `Lock`, but makes handling data in a thread-safe manner easier.
It encapsulates a type `T`, and guarantees no read or write to that value can result in race conditions:
```swift
classData{
privateletcalls=Atomic<Int>(0)
functhreadSafeIncrement()->Int{
returnself.calls.modify{callsin
calls+=1
returncalls
}
}
varthreadSafeValue:Int{
returnself.calls.value
}
}
```
### `SynchronizedUserDefaults`
Some places in the SDK (`DeviceCache` being one example) need to provide safety around reads and writes to `UserDefaults`.
`SynchronizedUserDefaults` can be used in such cases to provide the same guarantees. It's built on top of `Atomic`, so it works in a similar way: