线程分为前台和后台。比如我们直接new一个Thread这就是前台线程。

前台线程一定会执行。

比如我们创建2个线程:1号,2号,同时执行,假设1号是主线程,1执行完了,依旧会等待2执行完成,整个程序才会结束。

 

后台线程。

主线程执行完成以后,程序就结束了不会关心后台线程时候执行完毕。

这里说的后台线程主要用线程池(ThreadPool)来管理(这里的TheadPool是一个概念)。

 

ThreadPool和Task

这里的ThreadPool和Task都是微软实现的线程池的的封装的操作类。

.Net线程池第一代实现类ThreadPool

ThreadPool类实现方式是有一个全局的集合用来存放所有的待执行的线程。所有的CPU从这个队列面搭载待运行的线程来执行,因为用的是全局的队列,所有多核的情况下存在并发。

所以加了同步锁。而且这个集合采用的是先进先出的方式(队列)。

 

.Net线程池第二代实现类Task

Task类实现方式是在每一个核上创建自己的集合。任务来了就根据负载分配到各自集合里。但是集合这个采用的是先进后出的方式(栈).因为每个核只管自己的队列所有就少了同步锁的问题。这样就提高了执行效率。而且如果某一个核的队列里面暂时没有需要被执行的任务。还可以从其他的正在忙核的队列里把他的任务拿过来自己做。(个人觉得应该是从尾部拿,如果从头部拿的话就又有同步的问题了。所以这也是采用栈的好处)。

 

而Async 和 await

这2个关键字就是其实就是方便写异步操作的。

Async表示这是一个异步方法。这个一部方法直接调用的话就是交由后台线程池去管理。所以他返回的值是一个Task。

由于是线程池管理所以是后台线程。经常我们在同步调用Async的方法的时候就要加wait 关键字。否则我们主线程执行完了。后台线程有没有执行完,程序都结束了。

 

wait和await

wait是等待一个任务的结果,等到了再往下走。这里会堵塞当前线程,必须等到结果以后才往下走

await也是等待一个任务的结果,但是不堵塞当前线程。直到需要用到这个任务的结果了。才不得不等待。

所以await也只会出现在Async的方法中,因为只有异步的方法才存在这种情况。

 

但是要注意异步和多线程 这是2个不同概念。

因为即使是单线程也是可以异步的(比如javascript就是单线程,但是他也可以通过Ajax异步,Redis也是)。

 

所以虽然这里的Async方法叫异步方法而且一定是和多线程分不开的(因为他牵涉到task等等)

但要明白这里只是把异步和多线程联合在一起使用罢了。

 

posted on 2018-10-15 20:00  风灵ARCHER  阅读(226)  评论(0编辑  收藏  举报