Question: I have and Application which has a **singleton** that stores information across the whole app. However, this is creating some data race issues when using the singleton from different threads. 

Here there is a very dummy and simplistic version of the problem:

**Singleton**

```
class Singleton {
    static var shared = Singleton()

    var foo: String = "foo"
}

```

**Use of the singleton** (from the AppDelegate for simplicity)

```
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        DispatchQueue.global().async {
            var foo = Singleton.shared.foo // Causes data race
        }

        DispatchQueue.global().async {
            Singleton.shared.foo = "bar"   // Causes data race
        }

        return true
    }
}

```

Is there any way to ensure that a singleton is thread safe, so it can be used from anywhere in the app without having to worry about which thread you are in?

This question is **not** a duplicate of [Using a dispatch\_once singleton model in Swift](https://stackoverflow.com/questions/24024549/using-a-dispatch-once-singleton-model-in-swift) since (if I understood it correctly) in there they are addressing the problem of accessing to the singleton object itself, but not ensuring that the reading and writing of its properties is done thread safely.

Answer: 
Thanks to @rmaddy comments which pointed me in the right direction I was able to solve the problem. 

In order to make the property `foo` of the `Singleton` thread safe, it need to be modified as follows:

```
    class Singleton {

    static let shared = Singleton()

    private init(){}

    private let internalQueue = DispatchQueue(label: "com.singletioninternal.queue",
                                              qos: .default,
                                              attributes: .concurrent)

    private var _foo: String = "aaa"

    var foo: String {
        get {
            return internalQueue.sync {
                _foo
            }
        }
        set (newState) {
            internalQueue.async(flags: .barrier) {
                self._foo = newState
            }
        }
    }

    func setup(string: String) {
        foo = string
    }
}

```

Thread safety is accomplished by having a computed property `foo` which uses an `internalQueue` to access the "real" `_foo` property. 

Also, in order to have better performance `internalQueue` is created as concurrent. And it means that it is needed to add the `barrier` flag when writing to the property. 

What the `barrier` flag does is to ensure that the work item will be executed when all previously scheduled work items on the queue have finished.
**Swift Thread safe Singleton**

[[GCD]](https://stackoverflow.com/a/61102990/4770877)

[[Swift barrier flag for thread safe]](https://stackoverflow.com/questions/46732016/main-async-vs-main-sync-vs-global-async-in-swift3-gcd/61102990#61102990)

You are able to implement Swift's Singleton pattern for concurrent envirompment using `GCD` and 3 main things:

1. Custom **concurrent queue** - local queue for better performance where multiple reads can be happened at the same time
2. `sync` - `customQueue.sync` for **reading** a shared resource - to have clear API without callbacks
3. `barrier flag` - `customQueue.async(flags: .barrier)` for **writing** operation: wait when running operations are done -> execute write task -> proceed executing task

```
public class MySingleton {
    public static let shared = Singleton()

    //1. custom queue
    private let customQueue = DispatchQueue(label: "com.mysingleton.queue", qos: .default, attributes: .concurrent)
    //shared resource
    private var sharedResource: String = "Hello World"

    //computed property can be replaced getters/setters
    var computedProperty: String {
        get {
            //2. sync read
            return customQueue.sync {
                sharedResource
            }
        }
        set {
            //3. async write
            customQueue.async(flags: .barrier) {
                sharedResource = newValue
            }
        }
    }

    private init() {
    }
}

```