Welcome 微信登录

首页 / 网页编程 / ASP.NET / 浅谈.NET下的多线程和并行计算(三)线程同步基础 上

浅谈.NET下的多线程和并行计算(三)线程同步基础 上2011-08-03 博客园 lovecindywang其实,如果线程都是很独立的,不涉及到任何资源访问的,那么这些毫无干扰的线程不会产生什么问 题。但是在实际应用中我们的线程总是涉及到资源访问的,而且往往涉及到共享资源的访问,那么就产生 了线程同步的问题。一直觉得线程同步这个名词很奇怪,字面上看同步就是使得步调一致,线程同步是不 是就是让线程步调一致的访问资源呢?事实上反了,线程同步恰巧是让线程不同时去访问资源而是去按照 我们期望的顺序依次访问资源(是同步资源访问的行为而不是同步同时访问资源)。一句话,多个线程( 不仅仅局限于相同进程)如果需要访问相同的可变资源的话就可能需要考虑到线程同步的手段。还有两个 常见的名词是线程安全和线程冲突,所谓线程冲突就是由于多线程访问共享资源带来的问题,某个操作是 线程安全就是表明这个操作没有线程冲突问题,要达到线程安全就要用线程同步的手段来解决。在MSDN类 库中可以看到方法都注明了是不是线程安全的,如果不是那么我们在多线程程序总使用这个方法的话就要 考虑是否要线程同步了。

既然要让线程的步调一致,那么我们首先可以想到的是,如果一个线程没有完成我们就等,一直等到 它完成:

Stopwatch sw = Stopwatch.StartNew();
Thread t1 = new Thread(() =>
{
Thread.Sleep(1000);
result = 100;
});
t1.Start();
Thread.Sleep(500);
while (t1.IsAlive) ;
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(result);

假设线程在完成后会把结果写入result这么一个静态的变量,主线程在启动了新线程之后只花了500毫 秒就做好了自己的事情,接下去一定要等待线程计算完成之后才能进行后续的操作,这个时候我们通过不 断询问线程是不是还存在来得知线程是不是完成了计算,500毫秒后返回结果:

由于我们主线程是采用循环来等待的,对于处理器来说可不是等待,它足足运算了500毫秒,也就是浪 费了500毫秒处理器资源。其实,我们可以在循环中让线程休眠一小段时间,让出处理器时间片,然后再 去轮询检查,这样虽然不能在线程一完成后就得到结果,但是却节省了处理器资源:

Stopwatch sw = Stopwatch.StartNew();
Thread t1 = new Thread(() =>
{
Thread.Sleep(1000);
result = 100;
});
t1.Start();
Thread.Sleep(500);
while (t1.IsAlive)
Thread.Sleep(500);
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(result);

结果如下: