C#多线程详解(一) Thread.Join()的详解


什么是进程?

当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。

而一个进程又是由多个线程所组成的。


什么是线程?

线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。


什么是多线程?

多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。


多线程的好处:

可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。


多线程的不利方面:

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;

多线程需要协调和管理,所以需要CPU时间跟踪线程;

线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;

线程太多会导致控制太复杂,最终可能造成很多Bug;

接下来将对C#编程中的多线程机制进行探讨。为了省去创建GUI那些繁琐的步骤,更清晰地逼近线程的本质,接下来的所有程序都是控制台程序,程序最后的Console.ReadLine()是为了使程序中途停下来,以便看清楚执行过程中的输出。



示例:

using System;

using System.Threading;


namespace Test

{

    class TestThread

    {

        private static void FirstThreadFun()

        {

            for (int i = 0; i < 10; i++)

            {

                Console.WriteLine(Thread.CurrentThread.Name + "   i =  " + i);


            }

            Console.WriteLine(Thread.CurrentThread.Name + " 执行完毕");

        }


        static void Main(string[] args)

        {

            //程序调用了Main()函数时,就起动了一个进程,同时也启动了一个线程[这个线程就是主线程].

            Thread.CurrentThread.Name = "MainThread";


            //创建第一个线程

            Thread firstThread = new Thread(new ThreadStart(TestThread.FirstThreadFun));

            //取名为 firstThread

            firstThread.Name = "firstThread";


            for (int z = 0; z < 20; z++)

            {

                if (z == 10)

                {

                    firstThread.Start();

                    firstThread.Join();

                }

                else

                {

                    Console.WriteLine(Thread.CurrentThread.Name + "   z =  " + z);

                }

            }

            Console.Read();

        }

    }

}

运行结果:

C#多线程详解(一) Thread.Join()的详解_主线程


总结:

1.任何程序在执行时,至少有一个主线程。 

2.firstThread.Start()启动了一个线程后,用firstThread.Join()这个方法加入一个线程[即:暂停了主线程的运行],那么操作系统就会马上执行这个新加入的线程

3.Join 就是加入的意思,也就是说新创建的线程加入到进程中,并马上执行

4.如果只是 firstThread.Start(),把 firstThread.Join()方法注释掉会是什么结果?

下面的图是运行结果:

C#多线程详解(一) Thread.Join()的详解_多线程_02 

从运行结果可以看出:

1.如果只是 firstThread.Start(),注释掉 firstThread.Join()这个方法后,主线程并不会暂停[也就是说,firstThread 线程并不会马上执行]

2.所以要想一个线程在启动后就马上执行,必须调用 Thread.Join()方法.

3.到这里,Thread.Join()这个方法的作用也就明显了:当调用了 Thread.Join()方法后,当前线程会立即被执行,其他所有的线程会被暂停执行.

当这个线程执行完后,其他线程才会继续执行.


我们通过其中提供的Thread类来创建和控制线程,ThreadPool类用于管理线程池等。

(此外还提供解决了线程执行安排,死锁,线程间通讯等实际问题的机制。)


Thread类有几个至关重要的方法,描述如下:

Start():启动线程;

Sleep(int):静态方法,暂停当前线程指定的毫秒数;

Abort():通常使用该方法来终止一个线程;

Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;

Resume():恢复被Suspend()方法挂起的线程的执行;