这篇文章主要是为了整理 记录 c# 多线程 的理解


多线程:


首先呢,聊下我对多线程的理解.

在我看来,多线程就相当于分身术,就像火影忍者的分身术,你可以有很多分身来帮你做各种事情.

进程=你的本体

线程=分身

由你的本体创造出来很多分身

你可以让他们做各种事情。


比如想象一下 你要看 一本书,100页,那你分身100个 然后一人分一页给他们看。 那是不是提升了100倍速度。


还有 做饭 比如 你要做几个菜:清蒸石斑,油闷大虾...等等

那你就可以分身 几个人 让他们 分别去做某一道菜  这样也大大缩减了做菜的时间


但是如果灶只有一个呢,那么分身在处理食材的时候 只能谁处理完快,谁到需要用灶哪一步 谁先用,另外一些 就只能等待灶 空闲下来才能继续。


那么在程序里面是怎么解决的呢    Lock 代码块锁  先判断 是否灶已被占用,没被用 就占用  用完后然后释放掉给其他人 

示例:

        object 灶 = new object();//创建一个锅
        public void 做饭()
        {
            new Thread(() =>//做清蒸石斑的分身(线程)
            {
                //清洗
                //杀鱼
                //..
                lock (灶)//开始用灶
                {
                    //大火 
                    //小火
                    //直到菜好
                }

            }).Start();
            new Thread(() =>//做油闷大虾分身(线程)
            {
                //清洗
                //去须
                //..
                lock (灶)//开始用灶 
                {
                    //放油
                    //爆炒
                    //好吃了
                }

            }).Start();
        }


        //【时钟线程类别】
        //这一类型的有定时执行的效果,并且多数是占用主进程的资源

        //【Thread】
        //using System.Threading;命名空间下的
        //我平时最喜欢用的类
        //灵活,多变,简单
        /// <summary>
        /// 线程方法
        /// </summary>
        /// <param name="obj"></param>
        public void TheradMethod(object obj)
        {
            //创建一个线程
            Thread th = new Thread(() =>
            {
                //匿名委托 里面写线程 执行的操作
            });
            th.Start();
        }

        public void StartTh()
        {
            Thread th = new Thread(Method);//把方法委托给线程执行
            th.Start();
        }

        public void Method()
        {
        }

【Task】

System.Threading.Tasks

是线程池,由微软控制 封装了 如何分配 每个线程如何去执行 经测试是这样的:

下面 是 用Task跟Thread的区别

代码如下:

        //Task 线程
        private void button1_Click(object sender, EventArgs e)
        {
            int Ti = 0;
            int endTi = 0;
            System.Diagnostics.Stopwatch endsw = new System.Diagnostics.Stopwatch();
            endsw.Start();
            for (int i = 0; i < 10; i++)
            {
                new Task(() =>
                   {
                       Ti++;
                       System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                       sw.Start();

                       int n = Ti;
                       add(this.label2);

                       sw.Stop();

                       TimeSpan ts2 = sw.Elapsed;
                       listBox1.Invoke(new Action(() => { listBox1.Items.Add($"Task  {n} { sw.Elapsed}"); }));
                       endTi++;
                       if (endTi == 10)
                       {
                           endsw.Stop();
                           listBox1.Invoke(new Action(() => { listBox1.Items.Add($"Task END  { endsw.Elapsed}"); }));
                       }

                   }).Start();
            }
        }

        //Thread 线程
        private void button2_Click(object sender, EventArgs e)
        {
            int thi = 0, endthi = 0;
            System.Diagnostics.Stopwatch endsw = new System.Diagnostics.Stopwatch();
            endsw.Start();
            for (int i = 0; i < 10; i++)
            {
                //委托写法
                new Thread(() =>
                {
                    thi++;
                    int n = thi;
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    add(this.label1);
                    sw.Stop();

                    listBox1.Invoke(new Action(() => { listBox1.Items.Add($"Thread   {n}   { sw.Elapsed}"); }));

                    endthi++;
                    if (endthi == 10)
                    {
                        endsw.Stop();
                        listBox1.Invoke(new Action(() => { listBox1.Items.Add($"Thread END  { endsw.Elapsed}"); }));
                    }
                }).Start();
            }
        }

        System.Object locker = new System.Object();
        public void add(Control control)
        {
            // Access thread-sensitive resources.
            int i = 0;
            //Thread.Sleep(5000);
            while (i < 10000000)//运算的级别
            {
                //if (Interlocked.Exchange(ref intbool,1)==0)//多线程共享原子操作 保证完整性 为多个线程共享的变量提供原子操作
                //{
                //Thread.Sleep(10);//测试表明 如果多个线程同时刷新界面  那界面的响应也是具有 一定数量级的响应速度,如果超过了 就会卡住
                lock (locker)
                {
                    intbool = 1;

                    i++;

                    //control.Invoke(new Action(() =>
                    //{
                    //    control.Text = i.ToString();
                    //}));

                    //  Interlocked.Exchange(ref intbool, 0);
                }
            }

        }


运行结果如下:

    while (i < 10000000)//运算的级别




while (i < 100000000)//运算的级别  上一个运算结果的10倍



你会发现 他们总花费的时间是差不多的,

Task 是线程池来控制的

我猜

Thread 是并行 由 CPU 时间片时序来控制


并且他们都是 多核运算的。

TaskCUP图


Thread CPU图






未完待续




猜你喜欢

转载自blog.csdn.net/luopin102/article/details/73845265