首页 > 技术文章 > Thread 创建线程

bingyizhihun 2018-01-05 11:54 原文

      1.该线程变量 无参数 

 

   我们可以把线程的变量 理解为一个 委托。可以指向一个方法。有点像c语言中的指向函数的指针。 

   第1步我们创建了 Thread变量t1 ,第2步创建了一个方法threadChild()。第3步 这个委托 指向这个 threadChild()方法。  第4步 线程变量开始 执行 。

 

    第1个线程例子的代码如下:

   

 

 

     运行结果为:

 

 

      从以上例子我们可以得知: 程序都是从主线程开始的。  因为该线程是前台线程,所以结束方式 是主线程结束还是 子线程都可以。主线程结束时,进程也不会停止,继续运行子线程。具体前台线程和后台线程的例子,详见于例子4,例子5。

 

 

 

2. 给线程 传递 变量 :

    在上个例子中,我们的线程变量(委托)指向方法。但这个方法时无参的。当有需要给方法传参数的时候我们应该怎么做呢?  首先传入的参数不确定,为了保守起见。我们把函数的参数的类型 定义为object。 当我们传入 int类型的数据如30时,方法中的语句会自动把object类型的数据转为了 int类型的message。 然后在console输出语句中 ,输出这个message变量。  

 

 运行结果是:

 

 

 

3. 自定义类 实现带参数的线程 

        例子2虽然可以实现指向一个方法。但也有问题之处 ,比如说:如果我们需要传入的参数是 有int类型,也有 string类型,也有float类型。我们只写了一个int类型的方法,为了达到传入多个类型数据的要求,我们难道也要写入多个方法吗? 显然写多个 不同类型的方法,确实可以解决问题。  但这个方法的弊端在于:(1)从泛型的角度看: 1.你有几种类型,就要写多少次这个方法。 假设有3种类型,你就要写3个方法。这些方法的逻辑都差不多,只是类型稍微有些不同。重复写多次稍显得有些浪费。 2.从可扩展性的角度  ,假如说今天你有3种需要传入的类型,但是,可能明天要加1种类型,下个月又加1种类型,那么每添加一种类型,你就要修改一次。  维护代码也是要有成本的,这部分成本花的不大值的。     (2)   从安全性的角度看:涉及到object的装箱拆箱,对于数据来说有点不安全。 能避免应该尽量避免  。  (3) 从封装的角度看: 如果有一个方法 可以是 封装在一个 类里面,只有特定的对象才能够调用。相比于普通的static静态方法,封装在类里面的方法更好。     

 

      首先1.创建一个泛型类, 有一个泛型变量,泛型构造方法(该构造方法的参数也是泛型),也有一个普通方法。 2. 当创建变量的时候,传入参数。通过构造方法 赋值给泛型 变量。 3.创建 线程变量:并指向 对象.方法()。    委托想要指向方法必须要对象.。    3,子线程开始执行。

 

   于是具体的代码实现如下:

 

 

 

 

 

 

     

 

 4.前台线程  与  后台线程的对比:

     线程分为前台线程和 后台线程。Thread创建的线程默认为前台线程。只要有一个线程在运行,那么程序的进程就仍在激活状态。所以在多个子线程运行的时候,即使Main()线程执行完毕了,进行仍然是活的。直到所有线程都运行完, 进程才会歇下来。    前台线程的设定地方是:在创建线程变量的时候,IsBackground=false,即不是后台线程。

 

 

 

 

  在这个例子中,我们可以看到。子线程的开始和主线程的结束是不一定的,有时候是子线程先开始,有时候是主线程先结束。    但是最后一步一定是子线程的完成。 即使子线程没有sleep的操作,经过多次试验,子线程的完成也是最后一步。 

 

 

 

 

5.后台线程的练习:

   后台线程和前台线程的不同之处是。当有子线程和主线程在一起的时候,当主线程结束的时候,进程也会停止运行。那么子线程的剩余代码将不会再执行。经过多次试验,我也验证了 当主线程执行完毕后,"子线程运行完毕"这部分代码确实没有到,控制台也没有出现这几个文字了。     线程设置为后台线程 的地方在,线程的创建的时候,IsBackground设置为true。

 

 

 

后台线程一般用于处理不重要的事情,应用程序结束时,后台线程是否执行完成对整个应用程序没有影响。如果要执行的事情很重要,需要将线程设置为前台线程。

 

推荐阅读