多线程
一个应用程序至少包括一个进程,一个进程至少包括一个线程。程序需要在线程中执行,主线程由程序默认创建。单线程程序顺序执行,多线程程序同一时间可同时执行不同操作。
多线程的应用
线程的构造函数支持两种不同委托,一种不带参数的委托,一种带类型为object
的一个参数。
class Program
{
static void Main(string[] args)
{
ThreadStart ts = new ThreadStart(ThreadEntry);
Thread worker = new Thread(ts);
worker.Start();
ParameterizedThreadStart pts = new ParameterizedThreadStart(ThreadEntry);
Thread worker1 = new Thread(pts);
worker1.Start("Item4");
Console.WriteLine("Main Thread ends.");
Console.ReadKey();
}
static void ThreadEntry()
{
SharedResource resource = new SharedResource();
resource.Add("Item3");
}
static void ThreadEntry(object item)
{
SharedResource resource = new SharedResource();
string strItem = (string)item;
resource.Add(strItem);
}
}
public class SharedResource
{
public List<string> list = new List<string> { "Item0", "Item1", "Item2" };
public void Add(string item)
{
Console.WriteLine("Add" + item);
list.Add(item);
}
}
线程的属性与方法
ManagedThreadId
托管线程id,进程内唯一Name
线程名称,默认为空,开发者设置(不可修改)ThreadState
线程状态Thread.CurrentThread
获取当前线程Thread.Sleep(1000);
线程睡眠1sworker.IsBackground = true;
设置线程为后台线程,线程默认为前台线程,前台线程结束不管后台线程是否结束程序就会结束。worker.Join();
线程阻塞,等待worker
线程执行结束线程同步
CLR为每个线程分配了线程栈,用于保存本地变量,这样线程可以保证本地变量是独立的。但是线程外的变量对多线程是共享的。 针对多线程访问共享资源带来的问题两种解决方式 线程锁与线程通信
* * *
多线程同时访问变量问题:同时修改一个资源static void Print() { Console.WriteLine("i={0}",i); Thread.Sleep(1000); i++; } static void Main(string[] args) { ThreadStart ts1 = new ThreadStart(Print); Thread th1 = new Thread(ts1); th1.Start(); Print(); Console.ReadKey(); }
线程锁
线程锁:同一时间只允许单个线程访问代码区域。
static object olock = new object(); static int i = 0; static void Main(string[] args) { ThreadStart ts1 = new ThreadStart(Print); Thread th1 = new Thread(ts1); th1.Start(); Print(); Console.ReadKey(); } static void Print() { lock (olock) { Console.WriteLine("i={0}", i); Thread.Sleep(1000); i++; } }
lock
只能接受引用变量,并且应该保证变量唯一。线程信号
public class Resource { public string Data; } class Program { private Resource res = new Resource(); static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; Program p = new Program(); Thread worker = new Thread(p.ThreadEntry1); worker.Name = "Worker"; worker.Start(); lock (p.res) { if (string.IsNullOrEmpty(p.res.Data)) { //发送线程等待信号(Main线程等待) Monitor.Wait(p.res); } Console.WriteLine("Data={0}",p.res.Data); } Console.ReadKey(); } void ThreadEntry1() { lock (res) { res.Data = "Retrived"; //发送线程开始执行信号(向主线程发送开始信号) Monitor.Pulse(res); } } }
线程的处理类
更多线程处理的类,请查看
WaitHandle