Sync VS Async
sync
- 어떤 작업을 쓰레드에게 시켰을 때, 그 쓰레드가 작업을 모두 마치기 전까지 기다리는 것.
- 즉 A가 B에게 일을 시키면 A는 B가 일을 다 끝내기 전까지 기다리고 있음.
async
- 어떤 작업을 쓰레드에게 시키고, 반환을 기다리는 것이 아닌 다른 작업을 마저 하는 것.
- 즉 A가 B에게 일을 시키면 A는 B가 일을 다 끝내지 않아도 다른 작업을 C에게 시키거나 자기 일을 할 수 있음.
serial vs concurrnet
serial
- 한번에 하나의 작업만 처리 가능.(직렬)
- 즉 A라는 친구가 B라는 일을 하고 있으면 B라는 작업이 끝날 때 까지는 다른 작업을 하지 못함. 계속 해서 일을 줘도 일이 쌓이기만 함.
concurrent
- 한번에 여러개의 작업 처리 가능.(병렬)
- 즉 A라는 친구가 B라는 일을 처리하고 있는 와중에도, C라는 작업이 들어오면 동시에 처리 가능.
예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let concurrentQueue = DispatchQueue.global() // concurrentQueue
concurrentQueue.async {
(1...5).forEach {
print("🦊\($0)")
}
}
concurrentQueue.sync {
(1...5).forEach {
print("🐶\($0)")
}
}
concurrentQueue.async {
(1...5).forEach {
print("🦄\($0)")
}
}
위와 같은 코드는 어떻게 실행될까?
주어진 상황
- DispatchQueue.global() 는 한번에 여러개의 작업을 실행할 수 있는 concurrentQueue이다.
- 코드는 main.sync 내에서 돌아가며, serial 하다.
- async는 일을 시킨 사람이 끝나는 것을 기다리지 않는다.
- sync는 일을 시킨 사람이 일이 끝날 때 까지 기다린다.
결과
- 🦊를 5번 출력하는 작업이 들어온다. async이기 때문에 이 작업이 끝나기를 main이 기다리지 않고 다음 작업으로 넘어간다.
- 🐶를 5번 출력하는 작업이 들어온다. sync이기 때문에 이 작업이 끝나기를 main은 기다린다.
- 🐶를 5번 출력하는 작업이 끝난다.
- 이 때, 🦊를 5번 출력하는 작업은 끝나지 않았을 수도 있다.
- 🦄을 5번 출력하는 작업이 들어온다. async이기 때문에 이 작업이 끝나기를 main이 기다리지 않고 다음 작업으로 넘어간다.
즉 🦊와 🐶, 🦊와 🦄간의 상관관계는 없다. 하지만, 🐶가 모두 끝난 이후에 🦄이 실행된다는 것은 확실히 알 수 있다.