• 多线程(一)


    异步与多线程 

    1.异步和多线程概述

      计算机层面,我们对线程的概念并不陌生,我们打开任务管理器就能看到各种各样的进程,如下图所示

      我们电脑运行的程序我们都能看成一个进程。

      一个程序在运行时使用的全部的计算机资源的合集成为进程。例如我们的QQ音乐就是一个进程。

      同样,我们在任务管理器里面也能看不线程情况,如下图所示

     

      一个程序在响应一个操作是,使用的全部计算机资源合集称为线程。比如我们QQ音乐可以拖动(拖动对应一个线程)、听歌(也对应一个线程)

       那么进程和线程有什么关系呢?线程属于进程,一个进程包含多个线程,线程是计算机执行流的最小单位。

      在程序代码中,我们经常会听到多线程和异步,多线程和异步又是怎样的呢?

      我们先来看下同步和异步的定义。

      同步:发起调用后,要完成当前动作才能进行下一个动作。

      异步:发起调用后,直接进去下一个动作调用,不阻塞,当前动作可以和后续动作并行运行,完成后通知(回调方法)

      

    2.多线程使用

      在我们的程序开发中,多线程的使用十分广泛。在winform中,上传文件、提交操作、多线程防止界面卡死等。在web开发中,用户控制发邮件/短信等。

      注意,我们web开发中的ajax方法不是C#的异步,是HTTP请求的异步,发起请求后,可以继续往下执行

      我们接下来实现一个打印功能,来具体看下同步和异步的执行情况

      这是我们一个同步执行方法

    private void button1_Click(object sender, EventArgs e)
            {
                Console.WriteLine();
                Console.WriteLine("----------btn_同步 start {0}----------", Thread.CurrentThread.ManagedThreadId);
                for (int i = 0; i < 5; i++)
                {
                    string name = string.Format("{0}_{1}", "btn_同步", i);
                    print(name);
                }
                Console.WriteLine("----------btn_同步 end {0}----------",Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine();
                Console.ReadLine(); 
            }

    这是我们的异步执行方法:

    private void button2_Click(object sender, EventArgs e)
            {
                Console.WriteLine();
                Action<string> action = print;
                Console.WriteLine("----------btn_异步start {0}----------", Thread.CurrentThread.ManagedThreadId);
                for(int i=0;i<5;i++)
                {
                    string name = string.Format("{0}_{1}","btn_异步",i);
                    action.BeginInvoke(name,null,null);
                }
                Console.WriteLine("----------btn_异步end {0}----------", Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine();
                Console.ReadLine(); 
            }

    这是我们的打印方法:

    public void print(string name)
            {
                Console.WriteLine("线程{0}start {1}",Thread.CurrentThread.ManagedThreadId,DateTime.Now.ToString("HHmmss:ff"));
                int result = 0;
                for (int i = 0; i < 1000000000; i++)
                {
                    result += 1;
                }
                Console.WriteLine("线程{0}end {1}",Thread.CurrentThread.ManagedThreadId,DateTime.Now.ToString("HHmmss:ff"));
            }

    运行程序的输出结果如下图所示:

      从运行的结果可以看出,多线程执行的总耗时明显比同步执行的少。由此可以看出一定条件下,多线程能提升运行速度。我们理论上,异步执行这里添加了5个线程,理想情况下,异步的执行耗时应该为同步的5分之1.但事实并非如此。主要是因为:

      1.计算机资源有限,并不是5个线程就是5倍的资源。

      2.线程在进行调度的时候也会有时间上的损耗。

      因此,同步方法在执行过程中,只有一个线程执行,速度较异步慢。同步占用的CPU资源少,异步占用的CPU资源多。所以多线程也不是越多越好。

    3.异步和多线程的关系

      异步是一种效果,不阻塞,能并行,完成后通知

      多线程是一种手段,多个执行流去完成操作,以达到异步的效果。

      在开发过程中,异步都是通过多线程来实现的。

      异步也可以通过硬件层面来实现(DMP)

    4.多线程使用注意事项

    我们先来看下下面这两种情况能不能使用多线程。

      1.一个数据库的查询非常耗时,能不能多线程优化下?答案:肯定不能。操作数据库查询任务不能拆分,不能使用多线程。

      2.网站首页包含很多模块,数据接口、数据库查询,读取缓存等等,这种可以通过多线程优化吗?答案:可以的。因为各个模块之间可以拆分,能并行执行,所以可以使用多线程优化

    多线程给我们带来方便的同时,也给我们带来了些问题。

    从上图异步处理的过程中,我们可以看出,异步执行的顺序是乱的,每次执行的顺序可能都会有差别。因为多线程启动无序、运行无序、结束无序。线程来自操作系统,有自己的调度策略,无法掌控。所以我们在使用时可以控制线程的优先级。优先级的意义在于长期运行会拉开差距。

    对于怎么控制线程的执行顺序,我准备下一节内容再介绍了。

  • 相关阅读:
    【WCF】无废话WCF入门教程
    【IIS8】在IIS8添加WCF服务支持
    iOS 中如何将View设置为圆角的矩形?
    在iOS开发中使用FMDB
    iOS中FMDB的使用【单例】
    普通分页笔记
    基础BaseDao
    连接池技术 实现的四个要素:jdbc.properties配置- 读取配置的单例类 --ConfigManage--BaseDao写法
    反射生成对象,调用对象方法
    context分页
  • 原文地址:https://www.cnblogs.com/zxwDont/p/11662418.html
Copyright © 2020-2023  润新知