Exemplos de Multithreading macOS Swift

Exemplos de multithreading macOS Swift incluindo criação de threads, sincronização com locks e uso de pool de threads

💻 Criação de Threads swift

🟡 intermediate ⭐⭐⭐

Criar e gerenciar threads usando a classe Thread e DispatchQueue para execução de tarefas concorrentes

⏱️ 30 min 🏷️ swift, macos, multithreading, concurrency
Prerequisites: Intermediate Swift, Concurrency concepts
// macOS Swift Thread Creation Examples
// Using Foundation and Dispatch frameworks

import Foundation

// 1. Basic Thread using Thread Class
class BasicThread {

    // Create and start a thread using Thread class
    static func createBasicThread() {
        print("\n--- Basic Thread ---")

        let thread = Thread {
            print("Thread running: \(Thread.current)")
            print("Is main thread: \(Thread.isMainThread)")
            for i in 1...5 {
                print("Thread count: \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        thread.start()
        thread.join() // Wait for thread to complete
        print("Thread finished")
    }

    // Thread with parameters
    static func createThreadWithParameters() {
        print("\n--- Thread with Parameters ---")

        let thread = Thread {
            (name: String, count: Int) in
            for i in 1...count {
                print("\(name): \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        // Thread doesn't directly support init with parameters
        // Use a closure that captures variables
        let workerThread = Thread {
            let name = "Worker"
            let count = 3
            for i in 1...count {
                print("\(name): \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        workerThread.start()
        workerThread.join()
    }

    // Detached thread (fire and forget)
    static func createDetachedThread() {
        print("\n--- Detached Thread ---")

        Thread.detachNewThread {
            print("Detached thread executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Detached thread done")
        }

        print("Main thread continues immediately")
        Thread.sleep(forTimeInterval: 0.3) // Wait to see detached thread finish
    }

    // Multiple threads
    static func createMultipleThreads() {
        print("\n--- Multiple Threads ---")

        var threads: [Thread] = []

        for i in 1...3 {
            let thread = Thread {
                print("Thread \(i) started")
                for j in 1...3 {
                    print("Thread \(i): Step \(j)")
                    Thread.sleep(forTimeInterval: 0.1)
                }
                print("Thread \(i) finished")
            }
            threads.append(thread)
        }

        // Start all threads
        for thread in threads {
            thread.start()
        }

        // Wait for all threads to complete
        for thread in threads {
            thread.join()
        }

        print("All threads completed")
    }
}

// 2. DispatchQueue (Modern Swift Threading)
class DispatchQueueExample {

    // Global queue (background thread)
    static func globalQueueExample() {
        print("\n--- Global Queue ---")

        DispatchQueue.global(qos: .userInitiated).async {
            print("Background task executing")
            print("Is main thread: \(Thread.isMainThread)")

            // Simulate work
            Thread.sleep(forTimeInterval: 0.2)

            DispatchQueue.main.async {
                print("Back to main thread for UI update")
            }
        }

        Thread.sleep(forTimeInterval: 0.3)
    }

    // Custom queue
    static func customQueueExample() {
        print("\n--- Custom Queue ---")

        let customQueue = DispatchQueue(label: "com.example.customQueue", qos: .utility)

        customQueue.async {
            print("Task 1 on custom queue")
            Thread.sleep(forTimeInterval: 0.1)
        }

        customQueue.async {
            print("Task 2 on custom queue")
            Thread.sleep(forTimeInterval: 0.1)
        }

        customQueue.sync {
            print("Sync task on custom queue")
        }

        print("Custom queue tasks dispatched")
        Thread.sleep(forTimeInterval: 0.3)
    }

    // Serial queue
    static func serialQueueExample() {
        print("\n--- Serial Queue ---")

        let serialQueue = DispatchQueue(label: "com.example.serialQueue")

        print("Dispatching tasks to serial queue")

        serialQueue.async {
            for i in 1...3 {
                print("Task 1: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        serialQueue.async {
            for i in 1...3 {
                print("Task 2: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        serialQueue.async {
            for i in 1...3 {
                print("Task 3: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        Thread.sleep(forTimeInterval: 0.6)
        print("Serial queue tasks completed")
    }

    // Concurrent queue
    static func concurrentQueueExample() {
        print("\n--- Concurrent Queue ---")

        let concurrentQueue = DispatchQueue(
            label: "com.example.concurrentQueue",
            attributes: .concurrent
        )

        print("Dispatching tasks to concurrent queue")

        let group = DispatchGroup()

        for i in 1...3 {
            group.enter()
            concurrentQueue.async {
                for j in 1...3 {
                    print("Task \(i): Step \(j)")
                    Thread.sleep(forTimeInterval: 0.05)
                }
                group.leave()
            }
        }

        group.notify(queue: .main) {
            print("All concurrent tasks completed")
        }

        group.wait()
    }

    // Quality of Service levels
    static func qosExample() {
        print("\n--- Quality of Service (QoS) ---")

        DispatchQueue.global(qos: .userInteractive).async {
            print("User Interactive - Highest priority")
        }

        DispatchQueue.global(qos: .userInitiated).async {
            print("User Initiated - High priority")
        }

        DispatchQueue.global(qos: .utility).async {
            print("Utility - Low priority")
        }

        DispatchQueue.global(qos: .background).async {
            print("Background - Lowest priority")
        }

        Thread.sleep(forTimeInterval: 0.1)
    }
}

// 3. Operation and OperationQueue
class OperationExample {

    // Basic Operation
    static func basicOperation() {
        print("\n--- Basic Operation ---")

        let operation = BlockOperation {
            print("Operation executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Operation completed")
        }

        operation.start()
        operation.waitUntilFinished()
    }

    // Multiple operations
    static func multipleOperations() {
        print("\n--- Multiple Operations ---")

        let queue = OperationQueue()

        for i in 1...3 {
            let operation = BlockOperation {
                print("Operation \(i) executing")
                Thread.sleep(forTimeInterval: 0.1)
                print("Operation \(i) completed")
            }
            queue.addOperation(operation)
        }

        queue.waitUntilAllOperationsAreFinished()
        print("All operations completed")
    }

    // Operation with dependencies
    static func operationDependencies() {
        print("\n--- Operation Dependencies ---")

        let queue = OperationQueue()

        let op1 = BlockOperation {
            print("Operation 1 (Download)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        let op2 = BlockOperation {
            print("Operation 2 (Process)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        let op3 = BlockOperation {
            print("Operation 3 (Save)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        // Set dependencies: op1 -> op2 -> op3
        op2.addDependency(op1)
        op3.addDependency(op2)

        queue.addOperations([op3, op2, op1], waitUntilFinished: false)

        print("Operations queued with dependencies")
        queue.waitUntilAllOperationsAreFinished()
        print("Dependent operations completed")
    }

    // Custom Operation
    class CustomOperation: Operation {
        let name: String
        let duration: TimeInterval

        init(name: String, duration: TimeInterval) {
            self.name = name
            self.duration = duration
            super.init()
        }

        override func main() {
            if isCancelled { return }

            print("\(name) started")

            for i in 1...3 {
                if isCancelled {
                    print("\(name) cancelled")
                    return
                }
                print("\(name): Progress \(i)")
                Thread.sleep(forTimeInterval: duration / 3)
            }

            print("\(name) completed")
        }
    }

    static func customOperationExample() {
        print("\n--- Custom Operation ---")

        let queue = OperationQueue()

        let op1 = CustomOperation(name: "Task A", duration: 0.3)
        let op2 = CustomOperation(name: "Task B", duration: 0.2)

        queue.addOperations([op1, op2], waitUntilFinished: true)
        print("Custom operations completed")
    }
}

// 4. Thread Local Storage
class ThreadLocalStorage {

    static func threadLocalExample() {
        print("\n--- Thread Local Storage ---")

        // Using Thread.threadDictionary
        let thread = Thread {
            // Store thread-local data
            Thread.current.threadDictionary["threadID"] = "Thread-1"
            Thread.current.threadDictionary["counter"] = 0

            print("Thread ID: \(Thread.current.threadDictionary["threadID"] ?? "N/A")")

            for i in 1...3 {
                var count = Thread.current.threadDictionary["counter"] as? Int ?? 0
                count += 1
                Thread.current.threadDictionary["counter"] = count
                print("Local counter: \(count)")
                Thread.sleep(forTimeInterval: 0.05)
            }

            print("Final counter: \(Thread.current.threadDictionary["counter"] ?? "N/A")")
        }

        thread.start()
        thread.join()
    }
}

// 5. Thread Priority
class ThreadPriority {

    static func priorityExample() {
        print("\n--- Thread Priority ---")

        let highPriorityThread = Thread {
            print("High priority thread started")
            for i in 1...3 {
                print("High: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        let lowPriorityThread = Thread {
            print("Low priority thread started")
            for i in 1...3 {
                print("Low: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        // Set thread priorities (0.0 to 1.0)
        highPriorityThread.threadPriority = 1.0
        lowPriorityThread.threadPriority = 0.1

        highPriorityThread.start()
        lowPriorityThread.start()

        highPriorityThread.join()
        lowPriorityThread.join()
    }
}

// 6. Cancel Thread
class ThreadCancellation {

    static func cancellationExample() {
        print("\n--- Thread Cancellation ---")

        var shouldStop = false

        let thread = Thread {
            print("Worker thread started")

            for i in 1...10 {
                if shouldStop {
                    print("Thread cancelled at iteration \(i)")
                    return
                }

                print("Working... \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }

            print("Worker thread completed normally")
        }

        thread.start()

        // Cancel after 0.3 seconds
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
            print("Sending cancellation signal")
            shouldStop = true
        }

        thread.join()
        print("Thread handling completed")
    }
}

// 7. Async/Await (Swift 5.5+)
@available(macOS 12.0, *)
class ModernConcurrency {

    static func asyncAwaitExample() async {
        print("\n--- Async/Await ---")

        // Simple async function
        func fetchData() async -> String {
            print("Fetching data...")
            try? await Task.sleep(nanoseconds: 200_000_000)
            return "Data fetched"
        }

        let result = await fetchData()
        print(result)

        // Concurrent tasks
        async let task1 = fetchData()
        async let task2 = fetchData()

        let (r1, r2) = await (task1, task2)
        print("Results: \(r1), \(r2)")
    }

    // Task Group
    static func taskGroupExample() async {
        print("\n--- Task Group ---")

        let results = await withTaskGroup(of: Int.self) { group in
            var results: [Int] = []

            for i in 1...3 {
                group.addTask {
                    print("Task \(i) started")
                    try? await Task.sleep(nanoseconds: 100_000_000)
                    print("Task \(i) completed")
                    return i * 10
                }
            }

            for await result in group {
                results.append(result)
            }

            return results
        }

        print("Task group results: \(results)")
    }

    // Actor (Thread-safe reference type)
    actor Counter {
        private var value = 0

        func increment() -> Int {
            value += 1
            return value
        }

        func getValue() -> Int {
            return value
        }
    }

    static func actorExample() async {
        print("\n--- Actor Example ---")

        let counter = Counter()

        await counter.increment()
        await counter.increment()
        await counter.increment()

        let finalValue = await counter.getValue()
        print("Counter value: \(finalValue)")
    }
}

// 8. Thread with Completion Handler
class ThreadWithCompletion {

    static func completionExample() {
        print("\n--- Thread with Completion ---")

        func performWork(completion: @escaping (String) -> Void) {
            DispatchQueue.global().async {
                print("Work started")
                Thread.sleep(forTimeInterval: 0.2)
                let result = "Work completed"

                DispatchQueue.main.async {
                    completion(result)
                }
            }
        }

        performWork { result in
            print("Completion: \(result)")
        }

        Thread.sleep(forTimeInterval: 0.3)
    }
}

// 9. Run Loop
class RunLoopExample {

    static func runLoopTimerExample() {
        print("\n--- Run Loop Timer ---")

        var count = 0

        let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            count += 1
            print("Timer tick: \(count)")

            if count >= 3 {
                print("Timer finished")
                // In real app, you'd invalidate the timer
            }
        }

        // Run the loop for a short time
        RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.4))
        timer.invalidate()
    }
}

// Main demonstration
func demonstrateThreadCreation() {
    print("=== macOS Swift Thread Creation Examples ===")

    // 1. Basic Thread
    BasicThread.createBasicThread()
    BasicThread.createThreadWithParameters()
    BasicThread.createDetachedThread()
    BasicThread.createMultipleThreads()

    // 2. DispatchQueue
    DispatchQueueExample.globalQueueExample()
    DispatchQueueExample.customQueueExample()
    DispatchQueueExample.serialQueueExample()
    DispatchQueueExample.concurrentQueueExample()
    DispatchQueueExample.qosExample()

    // 3. Operation
    OperationExample.basicOperation()
    OperationExample.multipleOperations()
    OperationExample.operationDependencies()
    OperationExample.customOperationExample()

    // 4. Thread Local Storage
    ThreadLocalStorage.threadLocalExample()

    // 5. Thread Priority
    ThreadPriority.priorityExample()

    // 6. Cancellation
    ThreadCancellation.cancellationExample()

    // 7. Completion Handler
    ThreadWithCompletion.completionExample()

    // 8. Run Loop
    RunLoopExample.runLoopTimerExample()

    // 9. Modern Concurrency (if available)
    if #available(macOS 12.0, *) {
        Task {
            await ModernConcurrency.asyncAwaitExample()
            await ModernConcurrency.taskGroupExample()
            await ModernConcurrency.actorExample()
        }
    }

    print("\n=== All Thread Creation Examples Completed ===")
}

// Run demonstration
demonstrateThreadCreation()

💻 Sincronização de Threads swift

🟡 intermediate ⭐⭐⭐⭐

Sincronizar acesso de threads usando locks, semáforos, barreiras e variáveis de condição

⏱️ 40 min 🏷️ swift, macos, multithreading, synchronization
Prerequisites: Intermediate Swift, Thread concepts
// macOS Swift Thread Synchronization Examples
// Using Foundation and Dispatch frameworks

import Foundation

// 1. NSLock - Basic Mutex Lock
class LockExample {

    var counter = 0
    let lock = NSLock()

    // Unsafe increment (race condition)
    func unsafeIncrement() {
        let temp = counter
        Thread.sleep(forTimeInterval: 0.00001) // Simulate context switch
        counter = temp + 1
    }

    // Safe increment with lock
    func safeIncrement() {
        lock.lock()
        let temp = counter
        Thread.sleep(forTimeInterval: 0.00001)
        counter = temp + 1
        lock.unlock()
    }

    static func raceConditionDemo() {
        print("\n--- Race Condition Demo ---")

        let example = LockExample()

        // Unsafe version
        print("Unsafe increment:")
        var threads: [Thread] = []
        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.unsafeIncrement()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Unsafe result: \(example.counter) (expected: 1000)")

        // Reset
        example.counter = 0
        threads.removeAll()

        // Safe version
        print("\nSafe increment with lock:")
        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.safeIncrement()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Safe result: \(example.counter) (expected: 1000)")
    }

    // Try lock
    static func tryLockDemo() {
        print("\n--- Try Lock Demo ---")

        let lock = NSLock()
        var result = ""

        let thread1 = Thread {
            if lock.try() {
                print("Thread 1: Acquired lock immediately")
                Thread.sleep(forTimeInterval: 0.2)
                print("Thread 1: Releasing lock")
                lock.unlock()
            } else {
                print("Thread 1: Lock unavailable")
                result = "failed"
            }
        }

        let thread2 = Thread {
            Thread.sleep(forTimeInterval: 0.1)
            if lock.try() {
                print("Thread 2: Acquired lock")
                lock.unlock()
            } else {
                print("Thread 2: Lock busy, giving up")
                result = "busy"
            }
        }

        thread1.start()
        thread2.start()

        thread1.join()
        thread2.join()

        print("Result: \(result)")
    }
}

// 2. NSRecursiveLock
class RecursiveLockExample {

    let lock = NSRecursiveLock()
    var depth = 0

    func recursiveMethod(_ maxDepth: Int) {
        lock.lock()
        defer { lock.unlock() }

        depth += 1
        print("Recursive depth: \(depth)")

        if depth < maxDepth {
            recursiveMethod(maxDepth)
        }

        depth -= 1
    }

    static void recursiveLockDemo() {
        print("\n--- Recursive Lock Demo ---")

        let example = RecursiveLockExample()

        let thread = Thread {
            example.recursiveMethod(5)
        }

        thread.start()
        thread.join()

        print("Recursive method completed")
    }
}

// 3. NSConditionLock
class ConditionLockExample {

    let conditionLock = NSConditionLock(condition: 0)
    var data: String?

    // Producer
    func produce(_ value: String) {
        conditionLock.lock(whenCondition: 0) // Wait until condition is 0 (empty)
        data = value
        print("Produced: \(value)")
        conditionLock.unlock(withCondition: 1) // Set condition to 1 (has data)
    }

    // Consumer
    func consume() -> String? {
        conditionLock.lock(whenCondition: 1) // Wait until condition is 1 (has data)
        let value = data
        print("Consumed: \(value ?? "nil")")
        data = nil
        conditionLock.unlock(withCondition: 0) // Set condition back to 0 (empty)
        return value
    }

    static void conditionLockDemo() {
        print("\n--- Condition Lock Demo ---")

        let example = ConditionLockExample()
        var consumedValue: String?

        // Consumer thread
        let consumer = Thread {
            Thread.sleep(forTimeInterval: 0.1) // Wait for producer
            consumedValue = example.consume()
        }

        // Producer thread
        let producer = Thread {
            example.produce("Test Data")
        }

        consumer.start()
        producer.start()

        consumer.join()
        producer.join()

        print("Final consumed value: \(consumedValue ?? "nil")")
    }
}

// 4. DispatchQueue Barrier (Reader-Writer Lock)
class BarrierExample {

    private let queue = DispatchQueue(
        label: "com.example.barrierQueue",
        attributes: .concurrent
    )

    private var data: [String] = []

    // Read operation (concurrent)
    func read(completion: @escaping ([String]) -> Void) {
        queue.async {
            print("Reading data: \(self.data)")
            completion(self.data)
        }
    }

    // Write operation (exclusive with barrier)
    func write(_ value: String) {
        queue.async(flags: .barrier) {
            print("Writing: \(value)")
            self.data.append(value)
            Thread.sleep(forTimeInterval: 0.05) // Simulate write time
        }
    }

    static void barrierDemo() {
        print("\n--- Barrier Demo ---")

        let example = BarrierExample()

        // Initial writes
        example.write("Item 1")
        example.write("Item 2")

        Thread.sleep(forTimeInterval: 0.2)

        // Concurrent reads
        print("\nStarting concurrent reads:")
        let group = DispatchGroup()

        for i in 1...3 {
            group.enter()
            example.read { data in
                print("Reader \(i) got: \(data)")
                group.leave()
            }
        }

        // Write during reads (will wait)
        group.enter()
        queue.async(flags: .barrier) {
            example.write("Item 3 (barrier)")
            group.leave()
        }

        group.wait()
        print("\nBarrier demo completed")
    }
}

// 5. NSCondition
class ConditionExample {

    let condition = NSCondition()
    var isReady = false
    var data: String?

    // Wait for data
    func waitForData() -> String? {
        condition.lock()

        while !isReady {
            print("Waiting for data...")
            condition.wait()
        }

        let value = data
        isReady = false
        condition.unlock()
        return value
    }

    // Signal data ready
    func signalData(_ value: String) {
        condition.lock()
        data = value
        isReady = true
        print("Signaling data: \(value)")
        condition.signal()
        condition.unlock()
    }

    static void conditionDemo() {
        print("\n--- Condition Demo ---")

        let example = ConditionExample()

        // Consumer thread
        let consumer = Thread {
            if let data = example.waitForData() {
                print("Consumer received: \(data)")
            }
        }

        // Producer thread
        let producer = Thread {
            Thread.sleep(forTimeInterval: 0.2)
            example.signalData("Hello from producer!")
        }

        consumer.start()
        producer.start()

        consumer.join()
        producer.join()

        print("Condition demo completed")
    }
}

// 6. DispatchSemaphore
class SemaphoreExample {

    let semaphore = DispatchSemaphore(value: 3) // Max 3 concurrent accesses
    var activeCount = 0

    func accessResource(id: Int) {
        semaphore.wait() // Acquire

        activeCount += 1
        print("Resource \(id) accessing. Active: \(activeCount)")

        Thread.sleep(forTimeInterval: 0.2)

        activeCount -= 1
        print("Resource \(id) releasing. Active: \(activeCount)")

        semaphore.signal() // Release
    }

    static void semaphoreDemo() {
        print("\n--- Semaphore Demo ---")

        let example = SemaphoreExample()
        var threads: [Thread] = []

        // Create 5 threads but only 3 can access at a time
        for i in 1...5 {
            let thread = Thread {
                example.accessResource(id: i)
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Semaphore demo completed")
    }

    // Producer-Consumer with semaphores
    static void producerConsumerSemaphore() {
        print("\n--- Producer-Consumer with Semaphore ---")

        let bufferSemaphore = DispatchSemaphore(value: 5) // Buffer size
        let itemSemaphore = DispatchSemaphore(value: 0) // Items available
        var buffer: [Int] = []

        // Producer
        let producer = Thread {
            for i in 1...5 {
                bufferSemaphore.wait() // Wait for space
                buffer.append(i)
                print("Produced: \(i), Buffer: \(buffer)")
                itemSemaphore.signal() // Signal item available
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // Consumer
        let consumer = Thread {
            for _ in 1...5 {
                itemSemaphore.wait() // Wait for item
                if let item = buffer.first {
                    buffer.removeFirst()
                    print("Consumed: \(item), Buffer: \(buffer)")
                }
                bufferSemaphore.signal() // Signal space available
                Thread.sleep(forTimeInterval: 0.15)
            }
        }

        consumer.start()
        producer.start()

        producer.join()
        consumer.join()

        print("Producer-Consumer completed")
    }
}

// 7. Synchronized Block (using objc_sync_enter/exit)
class SynchronizedExample {

    var sharedResource = 0

    func safeOperation() {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        let temp = sharedResource
        Thread.sleep(forTimeInterval: 0.0001)
        sharedResource = temp + 1
    }

    static void synchronizedDemo() {
        print("\n--- Synchronized Block Demo ---")

        let example = SynchronizedExample()
        var threads: [Thread] = []

        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.safeOperation()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Synchronized result: \(example.sharedResource)")
    }
}

// 8. DispatchQueue.sync (Barrier-free synchronization)
class SyncDispatchExample {

    private let queue = DispatchQueue(label: "com.example.syncQueue")
    private var counter = 0

    func increment() {
        queue.sync {
            counter += 1
        }
    }

    func getCount() -> Int {
        return queue.sync {
            counter
        }
    }

    static void syncDemo() {
        print("\n--- Sync Dispatch Demo ---")

        let example = SyncDispatchExample()
        var threads: [Thread] = []

        for i in 1...5 {
            let thread = Thread {
                for _ in 1...100 {
                    example.increment()
                }
                print("Thread \(i) completed")
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Final count: \(example.getCount())")
    }
}

// 9. Atomic Operations (using OSAtomic)
class AtomicExample {

    // Using DispatchQueue for atomic-like behavior
    private let queue = DispatchQueue(label: "com.example.atomicQueue")
    private var _value = 0

    var value: Int {
        get { return queue.sync { _value } }
        set { queue.sync { _value = newValue } }
    }

    func incrementAndGet() -> Int {
        return queue.sync {
            _value += 1
            return _value
        }
    }

    static void atomicDemo() {
        print("\n--- Atomic Operations Demo ---")

        let example = AtomicExample()
        var threads: [Thread] = []

        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.incrementAndGet()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Atomic result: \(example.value)")
    }
}

// 10. Deadlock Prevention
class DeadlockExample {

    let lock1 = NSLock()
    let lock2 = NSLock()

    // Deadlock scenario
    func deadlockScenario() {
        print("\n--- Deadlock Scenario ---")

        let thread1 = Thread {
            print("Thread 1: Acquiring lock 1")
            self.lock1.lock()
            print("Thread 1: Lock 1 acquired")

            Thread.sleep(forTimeInterval: 0.1)

            print("Thread 1: Waiting for lock 2")
            self.lock2.lock()
            print("Thread 1: Lock 2 acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 1: Completed")
        }

        let thread2 = Thread {
            print("Thread 2: Acquiring lock 2")
            self.lock2.lock()
            print("Thread 2: Lock 2 acquired")

            Thread.sleep(forTimeInterval: 0.1)

            print("Thread 2: Waiting for lock 1")
            self.lock1.lock()
            print("Thread 2: Lock 1 acquired")

            self.lock1.unlock()
            self.lock2.unlock()
            print("Thread 2: Completed")
        }

        thread1.start()
        thread2.start()

        // This will deadlock - in practice, use timeout
        // For demo, we'll kill threads after timeout
        Thread.sleep(forTimeInterval: 0.3)
        print("Deadlock occurred (as expected)")
    }

    // Deadlock prevention with lock ordering
    func safeLockOrdering() {
        print("\n--- Safe Lock Ordering ---")

        let thread1 = Thread {
            print("Thread 1: Acquiring locks in order 1->2")
            self.lock1.lock()
            self.lock2.lock()
            print("Thread 1: Both locks acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 1: Completed")
        }

        let thread2 = Thread {
            print("Thread 2: Acquiring locks in order 1->2")
            self.lock1.lock()
            self.lock2.lock()
            print("Thread 2: Both locks acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 2: Completed")
        }

        thread1.start()
        thread2.start()

        thread1.join()
        thread2.join()

        print("Safe ordering completed")
    }
}

// Main demonstration
func demonstrateThreadSynchronization() {
    print("=== macOS Swift Thread Synchronization Examples ===")

    // 1. Basic Lock
    LockExample.raceConditionDemo()
    LockExample.tryLockDemo()

    // 2. Recursive Lock
    RecursiveLockExample.recursiveLockDemo()

    // 3. Condition Lock
    ConditionLockExample.conditionLockDemo()

    // 4. Barrier
    BarrierExample.barrierDemo()

    // 5. Condition Variable
    ConditionExample.conditionDemo()

    // 6. Semaphore
    SemaphoreExample.semaphoreDemo()
    SemaphoreExample.producerConsumerSemaphore()

    // 7. Synchronized
    SynchronizedExample.synchronizedDemo()

    // 8. Sync Dispatch
    SyncDispatchExample.syncDemo()

    // 9. Atomic
    AtomicExample.atomicDemo()

    // 10. Deadlock
    DeadlockExample().deadlockScenario()
    DeadlockExample().safeLockOrdering()

    print("\n=== All Thread Synchronization Examples Completed ===")
}

// Run demonstration
demonstrateThreadSynchronization()

💻 Pool de Threads swift

🔴 complex ⭐⭐⭐⭐⭐

Implementar padrão de pool de threads para execução eficiente de tarefas com gerenciamento de recursos

⏱️ 45 min 🏷️ swift, macos, multithreading, thread pool
Prerequisites: Advanced Swift, Thread concepts, Concurrency
// macOS Swift Thread Pool Examples
// Using OperationQueue and custom implementation

import Foundation

// 1. OperationQueue as Thread Pool
class OperationQueuePool {

    let queue: OperationQueue

    init(maxThreads: Int) {
        queue = OperationQueue()
        queue.maxConcurrentOperationCount = maxThreads
        queue.name = "com.example.operationPool"
    }

    func submit(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        queue.addOperation(operation)
    }

    func submitAndWait(_ tasks: [() -> Void]) {
        let operations = tasks.map { BlockOperation(block: $0) }
        queue.addOperations(operations, waitUntilFinished: true)
    }

    func shutdown() {
        queue.cancelAllOperations()
        queue.waitUntilAllOperationsAreFinished()
    }

    static void basicExample() {
        print("\n--- OperationQueue Pool ---")

        let pool = OperationQueuePool(maxThreads: 3)

        print("Submitting 10 tasks to pool of 3 threads")

        for i in 1...10 {
            pool.submit {
                print("Task \(i) executing on thread \(Thread.current.hashValue)")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) completed")
            }
        }

        pool.shutdown()
        print("All tasks completed")
    }
}

// 2. DispatchQueue Thread Pool
class DispatchQueuePool {

    private let workQueue: DispatchQueue
    private let semaphore: DispatchSemaphore

    init(maxThreads: Int) {
        workQueue = DispatchQueue(
            label: "com.example.dispatchPool",
            attributes: .concurrent
        )
        semaphore = DispatchSemaphore(value: maxThreads)
    }

    func submit(_ task: @escaping () -> Void) {
        workQueue.async {
            self.semaphore.wait()

            task()

            self.semaphore.signal()
        }
    }

    static void basicExample() {
        print("\n--- DispatchQueue Pool ---")

        let pool = DispatchQueuePool(maxThreads: 3)

        print("Submitting 8 tasks")

        for i in 1...8 {
            pool.submit {
                print("Task \(i) started")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) completed")
            }
        }

        Thread.sleep(forTimeInterval: 1.0) // Wait for completion
        print("DispatchQueue pool demo completed")
    }
}

// 3. Custom Thread Pool
class ThreadPool {

    private var threads: [Thread] = []
    private var taskQueue: [(String) -> Void] = []
    private let queueLock = NSLock()
    private let condition = NSCondition()
    private var isRunning = true

    init(threadCount: Int, name: String = "ThreadPool") {
        for i in 0..<threadCount {
            let thread = Thread {
                self.workerThread(id: i)
            }
            thread.name = "\(name)-\(i)"
            threads.append(thread)
        }
    }

    func start() {
        for thread in threads {
            thread.start()
        }
    }

    func submit(_ task: @escaping () -> Void) {
        queueLock.lock()
        taskQueue.append { _ in task() }
        queueLock.unlock()
        condition.signal()
    }

    func submitWithID(_ task: @escaping (String) -> Void) {
        queueLock.lock()
        taskQueue.append(task)
        queueLock.unlock()
        condition.signal()
    }

    func shutdown() {
        queueLock.lock()
        isRunning = false
        queueLock.unlock()
        condition.broadcast()

        for thread in threads {
            thread.join()
        }
    }

    private func workerThread(id: Int) {
        print("Worker thread \(id) started")

        while true {
            queueLock.lock()
            while taskQueue.isEmpty && isRunning {
                queueLock.unlock()
                condition.lock()
                condition.wait()
                condition.unlock()
                queueLock.lock()
            }

            if !isRunning {
                queueLock.unlock()
                break
            }

            let task = taskQueue.removeFirst()
            queueLock.unlock()

            task("Thread-\(id)")
        }

        print("Worker thread \(id) exiting")
    }

    static void basicExample() {
        print("\n--- Custom Thread Pool ---")

        let pool = ThreadPool(threadCount: 3, name: "CustomPool")
        pool.start()

        print("Submitting 10 tasks")

        for i in 1...10 {
            pool.submit {
                print("Task \(i) executing")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) done")
            }
        }

        Thread.sleep(forTimeInterval: 0.5)
        pool.shutdown()
        print("Custom pool shutdown complete")
    }
}

// 4. Future/Promise Pattern
class Future<T> {
    private var result: T?
    private var error: Error?
    private let condition = NSCondition()
    private var isCompleted = false

    func complete(with value: T) {
        condition.lock()
        result = value
        isCompleted = true
        condition.broadcast()
        condition.unlock()
    }

    func fail(with error: Error) {
        condition.lock()
        self.error = error
        isCompleted = true
        condition.broadcast()
        condition.unlock()
    }

    func get() throws -> T {
        condition.lock()
        while !isCompleted {
            condition.wait()
        }

        defer { condition.unlock() }

        if let error = error {
            throw error
        }

        return result!
    }

    func get(timeout: TimeInterval) throws -> T? {
        condition.lock()
        while !isCompleted {
            if !condition.wait(until: Date().addingTimeInterval(timeout)) {
                condition.unlock()
                return nil // Timeout
            }
        }

        defer { condition.unlock() }

        if let error = error {
            throw error
        }

        return result
    }
}

class Promise<T> {
    let future = Future<T>()

    func succeed(_ value: T) {
        future.complete(with: value)
    }

    func fail(_ error: Error) {
        future.fail(with: error)
    }

    var getFuture: Future<T> {
        return future
    }
}

// Thread Pool with Futures
class FutureThreadPool {

    private let pool = ThreadPool(threadCount: 3)

    init() {
        pool.start()
    }

    func submit<T>(_ task: @escaping () throws -> T) -> Future<T> {
        let promise = Promise<T>()

        pool.submit {
            do {
                let result = try task()
                promise.succeed(result)
            } catch {
                promise.fail(error)
            }
        }

        return promise.getFuture
    }

    deinit {
        pool.shutdown()
    }

    static void futureExample() {
        print("\n--- Future/Promise Thread Pool ---")

        let pool = FutureThreadPool()

        // Submit tasks and get futures
        let future1 = pool.submit { () -> Int in
            print("Task 1 executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Task 1 done")
            return 42
        }

        let future2 = pool.submit { () -> String in
            print("Task 2 executing")
            Thread.sleep(forTimeInterval: 0.1)
            print("Task 2 done")
            return "Hello"
        }

        // Wait for results
        do {
            let result1 = try future1.get()
            print("Future 1 result: \(result1)")

            let result2 = try future2.get()
            print("Future 2 result: \(result2)")
        } catch {
            print("Error: \(error)")
        }
    }
}

// 5. Priority Thread Pool
class PriorityThreadPool {

    let queue = OperationQueue()
    let highPriorityQueue = OperationQueue()
    let lowPriorityQueue = OperationQueue()

    init() {
        highPriorityQueue.maxConcurrentOperationCount = 2
        lowPriorityQueue.maxConcurrentOperationCount = 2
        queue.maxConcurrentOperationCount = 3
    }

    func submitHigh(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .high
        highPriorityQueue.addOperation(operation)
    }

    func submitNormal(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .normal
        queue.addOperation(operation)
    }

    func submitLow(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .low
        lowPriorityQueue.addOperation(operation)
    }

    func waitForAll() {
        highPriorityQueue.waitUntilAllOperationsAreFinished()
        queue.waitUntilAllOperationsAreFinished()
        lowPriorityQueue.waitUntilAllOperationsAreFinished()
    }

    static void priorityExample() {
        print("\n--- Priority Thread Pool ---")

        let pool = PriorityThreadPool()

        print("Submitting tasks with different priorities")

        // Low priority tasks
        for i in 1...3 {
            pool.submitLow {
                print("Low priority task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // Normal priority tasks
        for i in 1...2 {
            pool.submitNormal {
                print("Normal priority task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // High priority tasks
        pool.submitHigh {
            print("High priority task 1")
            Thread.sleep(forTimeInterval: 0.1)
        }

        pool.waitForAll()
        print("All priority tasks completed")
    }
}

// 6. Task Group (Modern Swift Concurrency)
@available(macOS 12.0, *)
class ModernTaskGroup {

    static void taskGroupExample() async {
        print("\n--- Modern Task Group ---")

        // Create task group
        await withTaskGroup(of: Int.self) { group in
            // Add tasks
            for i in 1...5 {
                group.addTask {
                    print("Task \(i) started")
                    try? await Task.sleep(nanoseconds: 100_000_000 * UInt64(i))
                    print("Task \(i) completed")
                    return i * 10
                }
            }

            // Collect results
            var results: [Int] = []
            for await result in group {
                results.append(result)
            }

            print("Task group results: \(results)")
        }
    }

    // Parallel map with task group
    static void parallelMapExample() async {
        print("\n--- Parallel Map ---")

        let items = [1, 2, 3, 4, 5]

        let results = await withTaskGroup(of: Int.self) { group in
            for item in items {
                group.addTask {
                    // Simulate async work
                    try? await Task.sleep(nanoseconds: 50_000_000)
                    return item * item
                }
            }

            var mapped: [Int] = []
            for await result in group {
                mapped.append(result)
            }
            return mapped.sorted()
        }

        print("Mapped results: \(results)")
    }

    // Concurrent data processing
    static void dataProcessingExample() async {
        print("\n--- Concurrent Data Processing ---")

        struct DataItem {
            let id: Int
            let value: String
        }

        let data = (1...10).map { DataItem(id: $0, value: "Item-\($0)") }

        let processed = await withTaskGroup(of: String.self) { group in
            for item in data {
                group.addTask {
                    // Simulate processing
                    try? await Task.sleep(nanoseconds: 30_000_000)
                    return "\(item.value)_processed"
                }
            }

            var results: [String] = []
            for await result in group {
                results.append(result)
            }
            return results
        }

        print("Processed \(processed.count) items")
    }
}

// 7. Work Stealing Thread Pool
class WorkStealingPool {

    private let globalQueue: DispatchQueue
    private let localQueues: [DispatchQueue]
    private let semaphore: DispatchSemaphore

    init(threadCount: Int) {
        globalQueue = DispatchQueue(label: "com.example.globalQueue")

        var queues: [DispatchQueue] = []
        for i in 0..<threadCount {
            let queue = DispatchQueue(
                label: "com.example.localQueue-\(i)",
                attributes: .concurrent
            )
            queues.append(queue)
        }
        localQueues = queues

        semaphore = DispatchSemaphore(value: threadCount)
    }

    func submit(task: @escaping () -> Void) {
        globalQueue.async {
            self.semaphore.wait()

            // In a real implementation, this would use work stealing
            // For simplicity, we just execute on a random local queue
            if let localQueue = self.localQueues.randomElement() {
                localQueue.async {
                    task()
                    self.semaphore.signal()
                }
            }
        }
    }

    static void workStealingExample() {
        print("\n--- Work Stealing Pool ---")

        let pool = WorkStealingPool(threadCount: 4)

        print("Submitting tasks to work stealing pool")

        for i in 1...12 {
            pool.submit(task: {
                print("Task \(i) executing")
                Thread.sleep(forTimeInterval: 0.05)
                print("Task \(i) done")
            })
        }

        Thread.sleep(forTimeInterval: 0.8)
        print("Work stealing demo completed")
    }
}

// 8. Resizeable Thread Pool
class ResizeableThreadPool {

    private var threads: [Thread] = []
    private var taskQueue: [() -> Void] = []
    private let lock = NSLock()
    private let condition = NSCondition()
    private var isRunning = true
    private var targetSize: Int

    init(initialSize: Int) {
        targetSize = initialSize
        resize(to: initialSize)
    }

    func resize(to newSize: Int) {
        lock.lock()
        targetSize = newSize
        lock.unlock()

        adjustThreads()
    }

    func submit(_ task: @escaping () -> Void) {
        lock.lock()
        taskQueue.append(task)
        lock.unlock()
        condition.signal()

        adjustThreads()
    }

    private func adjustThreads() {
        lock.lock()
        let currentCount = threads.count
        let needed = targetSize - currentCount
        lock.unlock()

        if needed > 0 {
            // Add threads
            for _ in 0..<needed {
                let thread = Thread { [weak self] in
                    self?.worker()
                }
                lock.lock()
                threads.append(thread)
                lock.unlock()
                thread.start()
            }
        } else if needed < 0 && currentCount > 0 {
            // Signal excess threads to exit (simplified)
        }
    }

    private func worker() {
        while true {
            lock.lock()
            while taskQueue.isEmpty {
                lock.unlock()

                condition.lock()
                condition.wait()
                condition.unlock()

                lock.lock()
                if !isRunning {
                    lock.unlock()
                    return
                }
            }

            let task = taskQueue.removeFirst()
            lock.unlock()

            task()
        }
    }

    static void resizeExample() {
        print("\n--- Resizeable Pool ---")

        let pool = ResizeableThreadPool(initialSize: 2)

        print("Initial size: 2")
        for i in 1...3 {
            pool.submit {
                print("Task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        Thread.sleep(forTimeInterval: 0.2)

        print("Resizing to 5")
        pool.resize(to: 5)

        for i in 4...8 {
            pool.submit {
                print("Task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        Thread.sleep(forTimeInterval(0.6))
        print("Resizeable pool demo completed")
    }
}

// Main demonstration
func demonstrateThreadPool() {
    print("=== macOS Swift Thread Pool Examples ===")

    // 1. OperationQueue Pool
    OperationQueuePool.basicExample()

    // 2. DispatchQueue Pool
    DispatchQueuePool.basicExample()

    // 3. Custom Pool
    ThreadPool.basicExample()

    // 4. Future/Promise Pool
    FutureThreadPool.futureExample()

    // 5. Priority Pool
    PriorityThreadPool.priorityExample()

    // 6. Work Stealing Pool
    WorkStealingPool.workStealingExample()

    // 7. Resizeable Pool
    ResizeableThreadPool.resizeExample()

    // 8. Modern Task Groups (if available)
    if #available(macOS 12.0, *) {
        Task {
            await ModernTaskGroup.taskGroupExample()
            await ModernTaskGroup.parallelMapExample()
            await ModernTaskGroup.dataProcessingExample()
        }
    }

    print("\n=== All Thread Pool Examples Completed ===")
}

// Run demonstration
demonstrateThreadPool()