单线程,多线程, 异步,同步,队列的使用场合和性能差异 返回

精华
6 5371

单线程

线程可以理解为一个轻量级的进程,单线程只能同时做一件事件,所以有很多局限性。例如我们的WEB服务器,每个用户都需要额外开一个线程,线程不但可以做同一件事情,也可以起到不错的隔离作用。


多线程

多线程可以理解为可以同时做几件事件,所以多线程可以充分利用CPU,但不意味个多个线程性能就快了几倍,在CPU满负荷的情况下,去处理同样量的事情时,性能是要慢于单线程的,因为 第一需要额外创建线程,第二会有线程阻塞。 

所以多线程只会提高程序执行的效率,并不能提高运行效率。


同步

首先要了解这么一个概念,单线程和多线程属于具体的计算机处理的实现,而同步和异步属于设计方案

例如可以这么讲:我把这个程序设计成了同步,使用了单线程去循环处理。


同步实现并非只有单线程,多线程也可以去实现同步,虽然少但是也有,概念理清楚后运用就自如了。


异步 

这里指的异步并非客户端JS的异步,为服务端的异步

就拿.NET MVC中的Action来讲,WEB 请求是基于多线程的,假设最大线程上限是100,当有200个用户的时候那就会出现100个用户进行等待,如果

使用了 异步Action,会将Action里面的内容,单独用一个线程去同步处理,所以执行结果是这样的


1.200个用户请求 

2.100线程执行完毕 ->将Action里面的执行操作指派给线程A

3.200线程执行完毕 ->将Action里面的执行操作指派给线程A

3.线程A执行完毕


注意:线程A是也可能是多个线程,我只是打个比方


那么异步到底能不能提高性能呢?

答:异步Action比同步的Action处理并发更加有效,从上面的例子可以看出线程和线程之间没有等待时间

把最浪费性能的地方交给独立的线程去处理。(当线程数达到上限并处于等待状态的时候是最浪费性能的时候)


在高并发的情况下,假设CPU利用率是百分之百,那么同步单线程>异步多线程>常规多线程,所以通过多线程和单线程相互配合实现了异步处理。(CPU利用率不高的情况下 同步单线程<异步多线程<=常规多线程 )


现在有很多ORM都支持了异步,但我认为是多余的,微软已经给我们提供了最优的方案那就是异步Action,将ORM里面的函数全部改成异步那就显的多此一举了,所以ORM的异步操作并没有太多使用场合。


ORM推荐使用SqlSugar ORM框架,因为他是性能最好的ORM框架


总结:就是把浪费时间的地方交给异步去做。


代码测试与验证

当前程序ThreadTest使用了Sleep暂停时间 所以CPU非常的闲,性能一定是多线程快

       public static void Main(string[] args)
        {
            Console.WriteLine("Single Thread");
            //同步单线程
            for (int i = 0; i < 10; i++)
            {
                ThreadTest();
            }


            Console.WriteLine("Multi Thread");
            //多线程
            for (int i = 0; i < 10; i++)
            {
               var t= new Thread(ThreadTest);
                t.Start();
            }

            Console.ReadKey();
        }
 
        public static  void ThreadTest()
        {
            
          Thread.Sleep(1000);
          Console.WriteLine("Thread ID:{0}\t\t\t\tTime:{1}",
              Thread.CurrentThread.ManagedThreadId, 
              DateTime.Now.ToString("HH:mm:ss"));
        }


让ThreadTest的CPU充份的利用,测试结果当然是单线程快

       public static void Main(string[] args)
        {
            Console.WriteLine("Single Thread");
            DateTime bt = DateTime.Now;
            //同步单线程
            for (int i = 0; i < 10000; i++)
            {
                ThreadTest();
            }
            Console.WriteLine((DateTime.Now-bt).TotalSeconds);

            bt = DateTime.Now;
            Console.WriteLine("Multi Thread");
            //多线程
            for (int i = 0; i < 10000; i++)
            {
               var t= new Thread(ThreadTest);
                t.Start();
            }
            Console.WriteLine((DateTime.Now - bt).TotalSeconds);
            Console.ReadKey();
        }
 
        public static  void ThreadTest()
        {

            for (int i = 0; i < 100000; i++)
            {
            }
        }


消息队列

从字面上可以看出消息队列是一个中间层 , 用户请求 -》消息队列-》数据处理。

那么我们为什么要有这么一个消息队列呢? 直接 用户请求=》数据处理不就完事了吗?

原因很简单,就是我们处理不过来了,消息队列可以是一个独立的服务器,对请求和数据处理进行解耦。

举个例子:

我们都知道蚂蚁是将食物一个一个搬进洞里面,慢慢享用,因为蚂蚁一下子吃不了那么多。

如果一下子全吃下去会把自个撑死,我们服务器也是这样一下子不能处理太多请求。

结论:

队列服务器就相当于蚁洞

请求的数据就相当于食物

数据处理就相当于蚂蚁吃食物


队列可以自已实现,也可以用现成的组件实现,只要知道他的原理,就变的非常简单

举个例子:

12306抢票总共10张票 100万人抢,这个时候就可以声名一个数组当数组数量等于100后,后面的请求直接返回false。然后定时推送这100条数据到数据处理服务器。

这样一台队列服务器就能解决百万的并发,他只处理了非常简单的内存操作,在差的PC也可以做的到。

热忱回答6

  • 老赵 老赵 VIP0
    2016/12/19

    高逼格!

    0 回复
  • 简单易懂。

    0 回复
  • 可以,工作上就是用不到数据量太少

    0 回复
  • 0 回复
  • 蓝の衫 蓝の衫 VIP0
    2016/12/28

    现在有很多ORM都支持了异步,但我认为是多余的,微软已经给我们提供了最优的方案那就是异步Action,将ORM里面的函数全部改成异步那就显的多此一举了,所以ORM的异步操作并没有太多使用场合。


    我感觉这句话不太对,异步action 返回Task<T>, 你要拿到这个异步对象必须要异步方法吧,所以我一用异步就必须异步到底,不然写在逻辑那里很麻烦,直接调用

    0 回复
  • Double Double VIP0
    2017/2/7

    关于队列的使用,有没有一个项目实例,来看一看

    0 回复

版块

学习文档

最新会员

发布达人

回贴达人