您的位置:首页 > 编程语言 > C#

C#OOP之十二 创建多线程程序

2016-04-30 07:52 471 查看


线程简介

在讲线程之前,我们先来看几个概念,程序、进程。

程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合。

进程:进程通俗的讲,就是正在执行的程序。一个进程通常就是一个正在执行的应用程序。Windows提供了“任务管理器”,如下图所示:



1教室.exe为海天屏幕广播程序的进程;飞球.exe为飞球的进程;sqlserver.exe为Sql Server2005的进程;当我们启动了一个应用程序(或者说一个任务)时通常也就启动了一个进程。从上图可以看出每一个进程占一定得内存空间和CPU,通过任务管理器,操作系统向我们显示了进程的一些重要信息。

定义与使用线程

在C#中如果使用线程,需要引用System.Threading命名空间。下面介绍线程类Thread,我们可以通过它创建并控制线程,设置线程优先级并获取其运行状态等。Thread类的属性和方法如下:

属性
说明
CurrentThread

获取当前正在运行的线程。

IsAlive

获取一个值,该值指示当前线程的执行状态。

IsBackground

获取或设置一个值,该值指示某个线程是否为后台线程。

Name

获取或设置线程的名称。

Priority

获取或设置一个值,该值指示线程的调度优先级。

ThreadState

获取一个值,该值包含当前线程的状态。

方法
说明
Start

开始执行线程

Abort

终止线程

Interrupt

打断处于WaitSleepJoin线程状态的线程,使其继续执行

Join

阻止调用线程,直到被调用线程终止,它在被调用线程实际停止之前或可选时间间隔结束之前不会返回。

Sleep

静态方法,使当前线程停止指定的毫秒数。

如果把进程比做公司,每个公司至少有个老板吧,那么程序里的老板叫主线程,,应用程序的主线程总是从Main()方法开始的,而后其他的线程需要在程序里自己定义和启动。

/*

摘要:主线程案例

*/

usingSystem;

usingSystem.Threading; //使用新的命名空间:System.Threading

namespaceThreadExam

{

class MainThread

{

public static void Main(string[]args)

{

Thread th=Thread.CurrentThread; //不是通过new出来,而是获取当前正在运行的线程.

th.Name="主线程"; //无默认名字.

Console.WriteLine("当前线程为:{0}",th.Name);

Console.ReadLine();

}

}

}效果如下图所示,显示设置给当前线程(Thread.CurrentThread)的名字为主线程:

现在公司大了,需要扩充业务,增加了新手,即增加了一个线程对象,既然是新人,就需要占用公司的资源(空间、电脑等),还得给开工资,当然最为重要是干活。^.^

那么新线程就得分配内存,下面来看一下Thread类的构造函数.

public Thread(

ThreadStartstart
)
ThreadStart委托,它使用此线程开始执行时要调用的方法。

构造函数中的参数为ThreadStart委托对象,ThreadStart对象需要的使用见第11章。

usingSystem;

usingSystem.Threading;

class BasicThread

{

static void BanZhuan() //静态方法.

{

Console.WriteLine("我开始搬砖了....."); //3 /2

}

public static void Main()

{

ThreadStart yueLiuYang=new ThreadStart(BanZhuan); //childRef:本质上为一委托;委托后跟(类名.静态方法)在同一类中,所以省略类名;

Console.WriteLine("主线程--创建子线程");//1 //1

Thread ChildThread=new Thread(yueLiuYang); //Thread构造函数中的参数就是委托对象!!!

ChildThread.Start(); //线程开始执行,通过委托中调用的方法来执行。

Console.WriteLine("主--请求子线程");//2 //3

Console.ReadLine();

}

}

执行效果如下图,先执行主线程,然后输出主线程中的语句,才开始子线程中的执行语句《我开始搬砖了….》。

线程的生命周期:



我们可以通过线程的属性ThreadState来获得线程的运行状态。ThreadState枚举包含线程的各种状态的定义,包含如下的成员:

n Aborted: 线程处于Stopped状态中

n AbortedRequested: 已对线程调用了Thread.Abort方法后的挂起状态

n Running:线程已启动,正在运行中

n Stopped:线程已停止

n Unstarted:尚未对线程调用Thread.Start方法

n WaitSleepJoin:由于调用Sleep或Join,线程已暂停

4 using System;

4 using System.Threading;

4

4 class BasicThread

4 {

4 static void BanZhuan() //静态方法.

4 {

4 Console.WriteLine("我开始搬砖了....."); //3 /2

4 }

4

4 public static void Main()

4 {

4 ThreadStart yueLiuYang=new ThreadStart(BanZhuan); //childRef:本质上为一委托;委托后跟(类名.静态方法)在同一类中,所以省略类名;

4

4 Console.WriteLine("主线程--创建子线程");//1 //1

4

4 Thread ChildThread=new Thread(yueLiuYang); //Thread构造函数中的参数就是委托对象!!!

4 ChildThread.Start(); //线程开始执行,通过委托中调用的方法来执行。

4

4 Console.WriteLine("主--请求子线程");//2 //3

4 Console.ReadLine();

4

4 }

4 }

线程的优先级

线程靠抢CPU时间片而执行,谁抢的多谁利用CPU的时间就多,当然执行更快。线程优先级决定了CPU时间的抢占,ThreadPriority枚举用来定义线程的优先级,默认情况下为ThreadPriority.Normal,一旦给线程设置了优先级,那么系统会根据线程的优先级调度线程的执行。

ThreadPriority枚举:

n Highest:优先级最高

n AboveNormal:处于Normal之上,而低于Highest

n Normal:默认优先级

n BelowNormal:处于Normal优先级之下,但高于Lowest优先级

n Lowest:最低优先级

整个级别由高到低位:

Highest>AboveNormal>Normal>BelowNormal>Lowest

usingSystem;

usingSystem.Threading;

class Test

{

static voidMain()

{

PriorityTest work =
new PriorityTest();

//创建线程并设置线程执行方法

Thread threadOne =
new Thread(new
ThreadStart(work.ThreadMethod));

threadOne.Name = "线程1";

threadOne.Priority = ThreadPriority.Highest;

Thread threadTwo =
new Thread(new
ThreadStart(work.ThreadMethod));

threadTwo.Name = "线程2";

//设置优先级

threadTwo.Priority = ThreadPriority.Lowest;

threadOne.Start();

threadTwo.Start();

//让两个线程都计算2秒钟

Thread.Sleep(2000);

//停止计算

work.LoopSwitch = false;

}

}

class PriorityTest

{

//用来控制While循环,为false就退出While循环

bool loopSwitch;

//构造方法

public PriorityTest()

{

loopSwitch = true;

}

public boolLoopSwitch

{

set { loopSwitch =
value; }

}

//线程的方法,执行数数操作

public voidThreadMethod()

{

long threadCount = 0;

//进行加法操作

while (loopSwitch) { threadCount++; }

//显示结果

Console.WriteLine("{0},优先级:{1}" +
"数到:{2}",
Thread.CurrentThread.Name,

Thread.CurrentThread.Priority.ToString(),

threadCount.ToString());

}

}

注意结果为优先级高的线程数要多一些,即执行的更快一些。还应注意,线程的优先级与平台有关。不同的操作系统对线程的调度不同,也就是说你在Windows下设的优先级到其他操作系统下可能不同。在实际应用中,不建议随便设置线程的优先级。

实践问题:

选择题:

1.下面哪个不属于未运行状态?

A.休眠 B.等待

C.阻塞 D.开始

2.多线程的执行顺序?

A.有顺序 B. 无顺序

C.通常情况下没有 D.可有可无

3.线程与进程是否是一个概念?【判断】

4.在多线程程序中,哪个类被用来构造和访问单线程?

A.System.Thread B. System.Threading

C.. System.Threading.Thread D. System.ThreadThreading:

5:哪个不属于线程的生命周期?

A:运行状态 B:未启动状态

C:启动状态 D:死亡状态

6:你在创建程序,使用多线程概念,在其中你可播放声音文件和同时观看动画片。应该对线程调用哪个方法使它进入运行状态?

A:start(); Bsleep();

C:Run(); D:Resume()

小结:

在本章中,我们主要学习了:

u 线程的概念

u 线程的定义与使用

u 什么是多线程

u 线程的同步

英语词汇:

英文 全文 中文

Thread 线路,流

Start 开始,启动

Sleep 暂停

Abort 中止,夭折

Suspend 暂停,中止

Resume 重新开始,恢复

Timeout 超时,无效

Infinite 无限的,无穷的

Waite 等待

Pluse 加法,正号,附加

AboveNomal 正常以上

BelowNomal 正常以下控制台

Highest 最高

Lowest 最低

Normal 正常

Running 进程中,流程

Monitor 监视器

Lock 锁定

Unlock 开锁

练习项目:

1.Hangman游戏:游戏要求用户输入一个类型做为书或电影。基于这个类型,书名或电影名被抽取,用户被要求通过给出字符和在串中的位置来猜测名称。用户将有60秒玩该游戏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: