// one of the global concurrent background queues
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or you could create your own serial background queue:
//
// dispatch_queue_t queue = dispatch_queue_create("com.domain.app.queuename", 0);
第二,将任务异步分派到该队列:
dispatch_async(queue, ^{
// the slow stuff to be done in the background
});
// Methods gets called in different thread and does not block the current thread.
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error) {
}];
下面的讨论很好地回答了这个问题:Asynchronous vs Multithreading - Is there a difference? 在一般情况下,异步调用不一定创建新线程。这是实现它的一种方式,而预先存在的线程池或外部进程是其他方式。它严重依赖于语言、对象模型(如果有的话)和运行时环境。 异步只是意味着调用线程不会等待响应,在调用线程中也不会发生异步活动。 因此,基本上,在等待加载某些内容时可能会发生其他活动,但这些活动可能在单独的线程上完成,也可能不在单独的线程上完成。
7条答案
按热度按时间vwhgwdsa1#
同步调用某个操作时,意味着启动该操作的线程将等待任务完成后再继续。异步意味着它不会等待。
话虽如此,当人们建议你异步执行一些缓慢或昂贵的进程时,他们暗示你不仅应该异步运行它,而且应该在后台线程上运行它。目标是释放主线程,以便它可以继续响应用户界面(而不是冻结),所以你是在异步地将任务分派给后台线程。
因此,这需要两个部分:首先,以GCD为例,获取一个后台队列(获取全局后台队列之一,或者创建自己的队列):
第二,将任务异步分派到该队列:
操作队列的模式非常相似。创建一个操作队列并向该队列添加操作。
实际上,同步与异步的区别与主队列与后台队列的区别完全不同,但是当人们谈论“异步运行一些慢的进程”时,他们实际上是在说“在后台队列上异步运行一些慢的进程”。
gcuhipw92#
**“同步”本质上意味着“按顺序"。**基本上,当您执行同步操作时,后面的所有操作都必须等待操作完成后才能开始。
相反,**“异步”或多或少意味着“不按顺序"。**当您异步执行某项操作时,下面的代码可以立即运行,并且异步操作将在某个时间运行。它可能与其他线程上的其余代码并行运行。它可能只是被安排在同一线程上的其他时间运行。
同步性的概念本质上与特定的线程无关,它只是关于你是否必须等待一个操作完成。
主要的线索是可可AppKit在主线程上运行主事件循环,因此如果主线程正在等待操作完成,它就不能处理任何输入或更新UI。不过,如果您有一段代码在后台线程上运行,则运行同步代码 * 不会阻塞主事件循环 *,因为等待同步操作完成的不是主线程。
类似地,从后台线程长时间运行的异步操作放在主线程上 * 可能 * 会导致问题,因为虽然后台线程不会等待操作完成,但它仍然会占用主线程上需要运行事件循环的时间。
myss37ts3#
让我们举一些简单的例子:
多线程异步调用:
多线程同步调用:
这里有//Do something //Do something else和//Do More things,它们是连续完成的,即使//Do something else是在不同的线程上完成的。
通常情况下,当人们使用不同的线程,整个目的是为了让一些事情可以得到执行,而无需等待。假设你想下载大量的数据,但你想保持界面流畅。
因此,dispatch_sync很少被使用。但是它就在那里。我个人从来没有使用过它。为什么不要求一些使用dispatch_sync的示例代码或项目呢?
使用一个线程的异步调用:
此处显示要在调用“doSomething”之前完成的当前runloop。换句话说,当前调用堆栈可以在调用“doSomething”之前完成(当前方法返回)。
与一个线程同步调用:
我觉得你不需要解释。
一般来说,异步活动与线程不同,但是在iOS中,它们是使用这种方式实现的。并非所有语言都是如此。我们通常使用运行循环来管理不同的异步任务。
dpiehjr44#
swift 3,4,4,2***Synchronous***表示启动该操作的线程将等待任务完成后再继续。
***异步***表示在后台完成任务并在完成时通知您,表示不会等待。
fcg9iug35#
异步意味着离线,同步意味着在线。您可以执行同步任务并同时阻塞多个线程。
如果你在一个后台线程中,想要更新一大堆用户界面,你可以调用
dispatch
队列中的主线程。如果你调用dispatch_sync
,那么你当前所在的代码将等待dispatch
完成,从而阻塞你所在的后台线程,并在它更新主线程时阻塞用户界面。但是,如果调用
dispatch_async
,后台线程将继续执行列出的其余代码,而主线程将运行请求的dispatch
块。在主线程中也是如此。如果你从主线程调用一个
dispatch_sync
到一个全局或自定义队列中,当主线程在一个单独的线程中运行代码时,它会阻塞主线程。我不能说我知道有这样的情况,但这肯定是可能的。当你有计算代码,网络服务代码,获取代码,诸如此类的不影响用户界面的东西时,最好在一个单独的线程中完成。对于这类东西,我会在一个全局线程中执行一个
dispatch_async
。然后当代码完成时,我会在主线程中运行一个dispatch_async
,告诉它用我刚刚计算的东西更新用户界面。同步意味着阻塞,异步意味着它将在以后某个时间(可能是现在)完成,而不会阻塞您当前正在执行的操作。
sycxhyv76#
下面的讨论很好地回答了这个问题:Asynchronous vs Multithreading - Is there a difference?
在一般情况下,异步调用不一定创建新线程。这是实现它的一种方式,而预先存在的线程池或外部进程是其他方式。它严重依赖于语言、对象模型(如果有的话)和运行时环境。
异步只是意味着调用线程不会等待响应,在调用线程中也不会发生异步活动。
因此,基本上,在等待加载某些内容时可能会发生其他活动,但这些活动可能在单独的线程上完成,也可能不在单独的线程上完成。
mum43rcc7#
同步和异步操作是关于下一个任务相对于当前任务的执行顺序。
让我们看一个例子,我们有三个任务(任务1、任务2、任务3),我们将通过任务2进行操作。任务是一个原子操作-堆栈(方法框架)中的方法调用。
意味着任务将一个接一个地执行,当前任务完成后才开始下一个任务,任务2完成后才开始任务3。
如果从主线程调用
DispatchQueue.main.sync
,则会导致死锁阻塞意味着线程只是在等待(尽管它可以做一些有用的事情,例如Java ExecutorService About(https://stackoverflow.com/a/66567556/4770877)和Future About(https://stackoverflow.com/a/66082407/4770877))
DispatchQueue.global().sync()
暗示任务立即返回控制,并承诺执行代码并在以后通知结果(例如回调、功能)。即使任务2未完成,也会执行任务3。异步回调,完成处理程序About(https://stackoverflow.com/a/60990583/4770877)
使用回调队列(消息队列)和事件循环(RunLoop、Looper)About(https://stackoverflow.com/a/75204210/4770877)。事件循环检查线程堆栈是否为空,如果为真,则将第一个项目从回调队列推入线程堆栈,并再次重复这些步骤。简单的示例是按钮单击、发布事件...
Timer.scheduledTimer(withTimeInterval: 2, repeats: false)
例如,当你需要在另一个线程上进行一些计算而不阻塞时,你可以使用阻塞方法get()或通过循环使用异步回调来使用任务2的结果。
DispatchQueue.global().async()
例如,在移动世界,我们有UI/主线程,我们需要下载的东西,我们有几个选项:
Concurrency vs Parallelism(https://stackoverflow.com/a/63744581/4770877)
iOS GCD(https://stackoverflow.com/a/61102990/4770877)
DispatchQueue sync vs async(https://stackoverflow.com/a/59542492/4770877)