c#线程学习笔记(一:线程的基本使用和线程安全)
大家好,本篇文章是分享个人在学习线程中的笔记分享,第一次写文章不足之处欢迎大家在评论里指出提醒,谢谢~
一、线程概念与基本使用
概念:线程是可以独立执行的执行路径,一个进程中包含多个线程,各个线程共享同一个执行环境。例如一个线程在后台获得数据,同时另一个线程显示所获得的数据,这些数据共享于这两个线程。
创建:假如有一个耗时方法叫DoSomething,那么可以这样用线程启动它:
Thread t = new Thread(DoSomething);
t.Start();
线程一旦启动,其IsAlive属性就会返回true,直至线程停止(当启动的方法执行完成就会停止),线程停止之后就无法再启动。
线程的汇合与休眠(即阻塞状态):
static void Main(){
Thread t = new Thread(DoSomething);
t.Start();
t.Join();
Console.WriteLine("Thread t has ended");
}
static void DoSomething()
{
for(int i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.WriteLine("Do Something-"+i);
}
}
以上代码中,t.Sleep(100)会让线程休眠100毫秒,函数DoSomething做了个自旋的操作模拟任务时长,t.Join会让Main函数等待t执行完成后再继续输出后面的内容。
二、锁与线程安全
1.共享资源可能发生的错误
class ThreadSafe{
static bool _flag;
static readonly object _locker = new object();
static void Main(){
new Thread (DoSomething).Start();
DoSomething();
}
static void DoSomething(){
if(!_flag){
Console.WriteLine("Do Something");
_flag =true;
}
}
}
看以上例子,Main方法中除了本身执行DoSomething外,还另起一个线程执行DoSomething,这样 _flag就会被两个线程访问,当第一个线程在将_flag改成true之前,另一个线程可能就已经进入if判断语句,这将但导致输出两行“Do Something”(假如这不是我们所希望的)
2.lock
我们可以在读写共享资源时用一个排他锁来修正前面的问题
static void DoSomething(){
lock(_locker){
if(!_flag){
Console.WriteLine("Do Something");
_flag =true;
}
}
}
3.使用monitor防止死锁
某些情形下,若使用锁不当,互相抢占资源而不释放,可能使程序陷入死锁中,可使用以下方式设置超时时间避免死锁问题
static void Method1(){
try
{
if (Monitor.TryEnter(_locker, 5000))//设置超时时间5000ms
{
//Do
}
}
finally
{
Monitor.Exit(_locker);
}
}
总结
提示:这里对文章进行总结:
以上就是今天要讲的内容,本文简单介绍了线程的基本概念和简单使用,后续线程相关内容将在下一章学习。