多线程
一个应用程序至少包括一个进程,一个进程至少包括一个线程。程序需要在线程中执行,主线程由程序默认创建。单线程程序顺序执行,多线程程序同一时间可同时执行不同操作。
多线程的应用
线程的构造函数支持两种不同委托,一种不带参数的委托,一种带类型为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