多线程-thread

来源:互联网 发布:淘宝网修改密码 编辑:程序博客网 时间:2024/05/19 23:10

Thread类有几个至关重要的方法:

Start():启动线程;
Sleep(int):静态方法,暂停当前线程指定的毫秒数;
Abort():通常使用该方法来终止一个线程;
Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;
Resume():恢复被Suspend()方法挂起的线程的执行;
使用Thread类创建线程时,只需提供线程入口即可。(线程入口使程序知道该让这个线程干什么事)

线程入口

(1)通过ThreadStart委托(delegate)来提供的,指向无返回值,无参数的方法,可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,当调用Thread.Start()方法后,线程就开始执行ThreadStart所代表或者说指向的函数。

Alpha oAlpha = new Alpha();
  Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
  oThread.Start(); //start中无参数
在创建线程oThread时我们用指向Alpha.Beta()方法的初始化了ThreadStart代理(delegate)对象,当我们创建的线程oThread调用oThread.Start()方法启动时,实际上程序运行的是Alpha.Beta()方法。

(2)还可以通过ParameterizedThreadStart委托把数据传递给在次线程上执行的方法。

AddParams ap = new AddParams(10, 10);

Thread t = new Thread(newParameterizedThreadStart(Add));

t.Start(ap);

这里将多个参数组合到一个类AddParams中,然后把这个类的实例作ap为参数传递,实现多个参数传递。

在创建线程t时指向Add函数,线程Start(ap);时将数据ap传递给Add函数,实现了传递参数的效果。

 

Thread.ThreadState 属性

这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。
Aborted:线程已停止;
AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;
Background:线程在后台执行,与属性Thread.IsBackground有关;
Running:线程正在正常运行;
Stopped:线程已经被停止;
StopRequested:线程正在被要求停止;
Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);
SuspendRequested:线程正在要求被挂起,但是未来得及响应;
Unstarted:未调用Thread.Start()开始线程的运行;
WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;

用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

给一个线程指定优先级,我们可以使用如下代码:
myThread.Priority=ThreadPriority.Lowest; //设定优先级为最低

 

lock关键字,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。在C#中,关键字lock定义如下:

lock(expression) statement_block
 expression代表你希望跟踪的对象,通常是对象引用。

如果保护一个类的实例,可以使用this;如果保护一个静态变量(如互斥代码段在一个静态方法内部),使用类名就可以了。

statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。

Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。
Monitor必须和一个具体的对象相关联,但是由于它是一个静态的类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。下面代码说明了使用Monitor锁定一个对象的情形:

Queue oQueue=new Queue();
Monitor.Enter(oQueue);     //Monitor和oQueue相关联
......//现在oQueue对象只能被当前线程操纵了
Monitor.Exit(oQueue);//释放锁  

如上所示,当一个线程调用Monitor.Enter()方法锁定一个对象时,这个对象就归它所有了,其它线程想要访问这个对象,只有等待它使用Monitor.Exit()方法释放锁。

为了保证线程最终都能释放锁,你可以把Monitor.Exit()方法写在try-catch-finally结构中的finally代码块里。

 

管理多线程:

1)应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应。使用ThreadPool(线程池)来解决;

ThreadPool :减少创建和销毁进程的消耗

ThreadPool.QueueUserWorkItem 方法运行我们在系统线程池上启动一个函数,它的声明如下:

public static bool QueueUserWorkItem (WaitCallback callBack, object state)
第一个参数指明我们将在池中执行的函数,它的声明必须与WaitCallback代理(delegate)互相匹配:public delegate void WaitCallback (object state);

State 参数允许任何类型的信息传递到该方法中,它在调用QueueUserWorkItem时传入。 例:

WaitCallback callBack  callBack = new WaitCallback(PooledFunc);

ThreadPool.QueueUserWorkItem(callBack,"Is there any screw left?");

2)线程平时都处于休眠状态,只是周期性地被唤醒。这一般使用Timer(定时器)来解决;

Timer类:设置一个定时器,定时执行用户指定的函数。定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数。

初始化一个Timer对象: Timer timer = new Timer(timerDelegate, s,1000, 1000);
// 第一个参数:指定了TimerCallback 委托,表示要执行的方法;
// 第二个参数:一个包含回调方法要使用的信息的对象,或者为空引用;
// 第三个参数:延迟时间——计时开始的时刻距现在的时间,单位是毫秒,指定为“0”表示立即启动计时器;
// 第四个参数:定时器的时间间隔——计时开始以后,每隔这么长的一段时间,TimerCallback所代表的方法将被调用一次,单位也是毫秒。指定 Timeout.Infinite 可以禁用定期终止。
Timer.Change()方法:修改定时器的设置。(这是一个参数类型重载的方法)。使用示例:  timer.Change(1000,2000);


 

原创粉丝点击