Swift Concurrency Programming (Dispatch Queues)

Image for post
Image for post
Photo by Kelly Sikkema on Unsplash

In the series of Concurrency programming, last time talked about Operation Queues, in this article will talk about whats the Dispatch Queues and how to use it .

Whats the Dispatch Queues

They are a powerful tool for performing tasks either asynchronously or synchronously with respect to the caller and they are simpler to use and much more efficient at executing those tasks than the corresponding threaded code.

All you need to use Dispatch Queues is add your code inside either a function or a block object and adding it to a dispatch queue, they are first-in, first-out data structures. Thus, the tasks you add to a queue are always started in the same order that they were added.

Types of dispatch queues

  • Serial : execute one task at a time in the order in which they are added to the queue, are often used to synchronize access to a specific resource and if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue .
  • Concurrent : execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The exact number of tasks executing at any given point is variable and depends on system conditions.
  • Main : globally available serial queue that executes tasks on the application’s main thread

Some other key points to remember about dispatch queues include the following:

  • Dispatch queues execute their tasks concurrently with respect to other dispatch queues.
  • The system determines the total number of tasks executing at any one time.
  • The system takes queue priority levels into account when choosing which new tasks to start.
  • Tasks in a queue must be ready to execute at the time they are added to the queue.

Creating and Managing Dispatch Queues

Before you add your tasks to a queue, you have to decide what type of queue to use and how you intend to use it. Dispatch queues can execute tasks either serially or concurrently.

Concurrent Dispatch Queues

A concurrent dispatch queue is useful when you have multiple tasks that can run in parallel. A concurrent queue is still a queue in that it dequeues tasks in a first-in, first-out order; however, a concurrent queue may dequeue additional tasks before any previous tasks finish. The actual number of tasks executed by a concurrent queue at any given moment is variable and can change dynamically as conditions in your application change. Many factors affect the number of tasks executed by the concurrent queues, including the number of available cores, the amount of work being done by other processes, and the number and priority of tasks in other serial dispatch queues.

You can create a Concurrent Dispatch Queues with priority:

Image for post
Image for post
DispatchQueue X  0
DispatchQueue Y 5
DispatchQueue Z 10
DispatchQueue X 1
DispatchQueue Y 6
DispatchQueue X 2
DispatchQueue Z 11
DispatchQueue Y 7
DispatchQueue X 3
DispatchQueue Z 12
DispatchQueue Y 8
DispatchQueue X 4
DispatchQueue Y 9
DispatchQueue Z 13
DispatchQueue Z 14

if you create two dispatch queues and set different priority like

Creating Serial Dispatch Queues

Serial queues are useful when you want your tasks to execute in a specific order. A serial queue executes only one task at a time and always pulls tasks from the head of the queue. You might use a serial queue instead of a lock to protect a shared resource or mutable data structure.

let dispatchQueue1 = DispatchQueue.init(label: "dispatchQueue")dispatchQueue1.sync {for i in 0..<5 {print("DispatchQueue X ", i)}}dispatchQueue1.sync {for i in 0..<5 {print("DispatchQueue Y ", i)}}DispatchQueue X  0DispatchQueue X  1DispatchQueue X  2DispatchQueue X  3DispatchQueue X  4DispatchQueue Y  0DispatchQueue Y  1DispatchQueue Y  2DispatchQueue Y  3DispatchQueue Y  4

Performing Tasks on the Main Thread

You can use to execute tasks on your application’s main thread.

DispatchQueue.main.async {
//put your work here
}

Waiting on Groups of Queued Tasks

Dispatch groups are a way to block a thread until one or more tasks finish executing. You can use this behavior in places where you cannot make progress until all of the specified tasks are complete.

DispatchQueue X  0DispatchQueue X  1DispatchQueue X  2DispatchQueue X  3DispatchQueue X  4DispatchQueue Y  0DispatchQueue Y  1DispatchQueue Y  2DispatchQueue Y  3DispatchQueue Y  4Dispatch group finished the work

but if you need to return value and need to wait for the Dispatch group.

func myFunction() -> Int? {
var a: Int?

let group = DispatchGroup()
group.enter()

// avoid deadlocks by not using .main queue here
DispatchQueue.global(attributes: .qosDefault).async {
a = 1
group.leave()
}

// wait ...
group.wait()

// ... and return as soon as "a" has a value
return a
}

Written by

Senior iOS Developer, Berlin, Germany

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store