多线程学习笔记1
Start():启动线程;
Sleep(int):静态方法,暂停当前线程指定的毫秒数;
Abort():通常使用该方法来终止一个线程;
Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;
Resume():恢复被Suspend()方法挂起的线程的执行;
Join():使主线程等待,直到子线程结束。
Thread.ThreadState 属性
这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。
ThreadState 属性的取值如下:
Aborted:线程已停止;
AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;
Background:线程在后台执行,与属性Thread.IsBackground有关;
Running:线程正在正常运行;
Stopped:线程已经被停止;
StopRequested:线程正在被要求停止;
Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);
SuspendRequested:线程正在要求被挂起,但是未来得及响应;
Unstarted:未调用Thread.Start()开始线程的运行;
WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;
上面提到了 Background状态表示该线程在后台运行,那么后台运行的线程有什么特别的地方呢?其实后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序 的终止。一旦一个进程所有的前台线程都终止后,CLR(通用语言运行环境)将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。
线程的优先级
当线程之间争夺CPU时间时,CPU 是按照线程的优先级给予服务的。在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。
给一个线程指定优先级,我们可以使用如下代码:
//设定优先级为最低
myThread.Priority=ThreadPriority.Lowest;
通过设定线程的优先级,我们可以安排一些相对重要的线程优先执行,例如对用户的响应等等。
C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。
Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。
Monitor.Enter(对象);
Monitor.Exit(对象);//释放锁
//等待WriteToCell方法中调用Monitor.Pulse()方法
Monitor.Wait(this);线程等待
Monitor.Pulse(this)方法通知等待队列中的第一个线程,于是该线程被转移到预备队列中,当对象锁被释放时,在预备队列中的线程可以立即获得对象锁。
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Call c = new Call();
WriteCall w = new WriteCall(c, 20);
ReadCall r = new ReadCall(c, 20);
Thread thw =new Thread(new ThreadStart(w.Threadgo));
Thread thr = new Thread(new ThreadStart(r.Threadgo));
thr.Start();
thw.Start();
thr.Join();
thw.Join();
Console.Read();
}
}
public class Call
{
int count = 0;
bool IscanWrite = true;
public void Write(int n)
{
lock (this)
{
if (!IscanWrite)
{
Monitor.Wait(this);
}
count = n;
Console.WriteLine("write count={0}", count);
IscanWrite = false;
Monitor.Pulse(this);
}
}
public int Read()
{
lock (this)
{
if (IscanWrite)
{
Monitor.Wait(this);
}
Console.WriteLine("read count={0}", count);
IscanWrite = true;
Monitor.Pulse(this);
}
return count;
}
}
public class WriteCall
{
Call _call;
int _count;
public WriteCall(Call call,int count)
{
this._call = call;
this._count = count;
}
public void Threadgo()
{
for(int i=1;i<=_count;i++)
{
_call.Write(i);
}
}
}
public class ReadCall{
public ReadCall(Call call,int count)
{
this._call = call;
this._count = count;
}
Call _call;
int _count;
public void Threadgo()
{
for(int i=1;i<=_count;i++)
{
_call.Read();
}
}
}
}